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.

5845 lines
170 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 dirname(__FILE__).'/../include/CAPITest.php';
require_once dirname(__FILE__).'/../../include/classes/parsers/CConditionFormula.php';
require_once dirname(__FILE__).'/../../include/classes/helpers/CConditionHelper.php';
/**
* @backup items
*/
class testDiscoveryRule extends CAPITest {
public static function discoveryrule_create_data_invalid() {
return [
'Test invalid permissions to host' => [
'discoveryrule' => [
'name' => 'API LLD rule invalid permissions',
'key_' => 'apilldruleinvalidpermissions',
'hostid' => '1',
'type' => ITEM_TYPE_ZABBIX,
'interfaceid' => '50022',
'delay' => '30s'
],
'expected_error' => 'No permissions to referred object or it does not exist!'
],
'Test invalid interface ID' => [
'discoveryrule' => [
'name' => 'API LLD rule invalid interface',
'key_' => 'apilldruleinvalidinterface',
'hostid' => '50009',
'type' => ITEM_TYPE_ZABBIX,
'interfaceid' => '1',
'delay' => '30s'
],
'expected_error' => 'Invalid parameter "/1/interfaceid": cannot be the host interface ID from another host.'
],
'Test if LLD rule name and key already exists' => [
'discoveryrule' => [
'name' => 'API LLD rule 4',
'key_' => 'apilldrule4',
'hostid' => '50009',
'type' => ITEM_TYPE_ZABBIX,
'interfaceid' => '50022',
'delay' => '30s'
],
'expected_error' => 'An LLD rule with key "apilldrule4" already exists on the host "API Host".'
],
'Test without update interval for mqtt.get key of Agent type' => [
'discoveryrule' => [
'name' => 'API mqtt.get',
'key_' => 'mqtt.get[test]',
'hostid' => '50009',
'type' => ITEM_TYPE_ZABBIX,
'interfaceid' => '50022'
],
'expected_error' => 'Invalid parameter "/1": the parameter "delay" is missing.'
],
'Test 0 update interval for mqtt.get key of Agent type' => [
'discoveryrule' => [
'name' => 'API mqtt.get',
'key_' => 'mqtt.get[test]',
'hostid' => '50009',
'type' => ITEM_TYPE_ZABBIX,
'interfaceid' => '50022',
'delay' => '0'
],
'expected_error' => 'Invalid parameter "/1/delay": cannot be equal to zero without custom intervals.'
],
'Test 0 update interval for wrong mqtt key of Active agent type' => [
'discoveryrule' => [
'name' => 'API mqtt.get',
'key_' => 'mqt.get[test]',
'hostid' => '50009',
'type' => ITEM_TYPE_ZABBIX_ACTIVE,
'delay' => '0'
],
'expected_error' => 'Invalid parameter "/1/delay": cannot be equal to zero without custom intervals.'
],
'Test LLD rule with unsupported item type' => [
'discoveryrule' => [
'name' => 'API LLD rule with unsupported item type',
'key_' => 'api_lld_rule_with_unsupported_item_type',
'hostid' => '50009',
'type' => '100',
'interfaceid' => '50022',
'delay' => '30s'
],
'expected_error' => 'Invalid parameter "/1/type": value must be one of '.implode(', ', [
ITEM_TYPE_ZABBIX, ITEM_TYPE_TRAPPER, ITEM_TYPE_SIMPLE, ITEM_TYPE_INTERNAL, ITEM_TYPE_ZABBIX_ACTIVE,
ITEM_TYPE_EXTERNAL, ITEM_TYPE_DB_MONITOR, ITEM_TYPE_IPMI, ITEM_TYPE_SSH, ITEM_TYPE_TELNET,
ITEM_TYPE_JMX, ITEM_TYPE_DEPENDENT, ITEM_TYPE_HTTPAGENT, ITEM_TYPE_SNMP, ITEM_TYPE_SCRIPT
]).'.'
]
];
// TODO: add other properties, multiple rules, duplicates etc.
}
public static function discoveryrule_create_data_valid() {
$valid_item_types = [
ITEM_TYPE_ZABBIX => '50022',
ITEM_TYPE_TRAPPER => null,
ITEM_TYPE_SIMPLE => '50022',
ITEM_TYPE_INTERNAL => null,
ITEM_TYPE_ZABBIX_ACTIVE => null,
ITEM_TYPE_EXTERNAL => '50022',
ITEM_TYPE_DB_MONITOR => null,
ITEM_TYPE_IPMI => '50031',
ITEM_TYPE_SSH => '50022',
ITEM_TYPE_TELNET => '50022',
ITEM_TYPE_JMX => '50030',
ITEM_TYPE_DEPENDENT => null,
ITEM_TYPE_HTTPAGENT => '50022',
ITEM_TYPE_SNMP => '50029'
];
$item_type_tests = [];
foreach ($valid_item_types as $type => $interfaceid) {
switch ($type) {
case ITEM_TYPE_ZABBIX:
case ITEM_TYPE_SIMPLE:
case ITEM_TYPE_INTERNAL:
case ITEM_TYPE_ZABBIX_ACTIVE:
case ITEM_TYPE_EXTERNAL:
$params = [
'delay' => '30s'
];
break;
case ITEM_TYPE_TRAPPER:
$params = [
'delay' => '0'
];
break;
case ITEM_TYPE_DB_MONITOR:
$params = [
'params' => 'SELECT * FROM table',
'delay' => '30s'
];
break;
case ITEM_TYPE_IPMI:
$params = [
'ipmi_sensor' => '1.2.3',
'delay' => '30s'
];
break;
case ITEM_TYPE_SSH:
$params = [
'username' => 'username',
'authtype' => ITEM_AUTHTYPE_PASSWORD,
'params' => 'return true;',
'delay' => '30s'
];
break;
case ITEM_TYPE_TELNET:
$params = [
'username' => 'username',
'params' => 'return true;',
'delay' => '30s'
];
break;
case ITEM_TYPE_JMX:
$params = [
'username' => 'username',
'password' => 'password',
'delay' => '30s'
];
break;
case ITEM_TYPE_DEPENDENT:
$params = [
'master_itemid' => '150151',
'delay' => '0'
];
break;
case ITEM_TYPE_HTTPAGENT:
$params = [
'url' => 'http://0.0.0.0',
'delay' => '30s'
];
break;
case ITEM_TYPE_SNMP:
$params = [
'snmp_oid' => '1.2.3',
'delay' => '30s'
];
break;
case ITEM_TYPE_SCRIPT:
$params = [
'params' => 'script',
'timeout' => '30s',
'delay' => '30s'
];
break;
default:
$params = [];
break;
}
if ($interfaceid) {
$params['interfaceid'] = $interfaceid;
}
$item_type_tests['Test valid LLD rule with item type '.$type] = [
'discoveryrule' => $params + [
'name' => 'LLD rule of type '.$type,
'key_' => 'lld_rule_of_type_'.$type,
'hostid' => '50009',
'type' => (string) $type
],
'expected_error' => null
];
}
return [
'Test 0 update interval for mqtt.get key of Active agent type' => [
'discoveryrule' => [
'name' => 'API LLD rule mqtt',
'key_' => 'mqtt.get[0]',
'hostid' => '50009',
'type' => ITEM_TYPE_ZABBIX_ACTIVE,
'delay' => '0'
],
'expected_error' => null
],
'Test without update interval for mqtt.get key of Active agent type' => [
'discoveryrule' => [
'name' => 'API LLD rule mqtt',
'key_' => 'mqtt.get[1]',
'hostid' => '50009',
'type' => ITEM_TYPE_ZABBIX_ACTIVE
],
'expected_error' => null
]
] + $item_type_tests;
// TODO: add other properties, multiple rules, duplicates etc.
}
/**
* @dataProvider discoveryrule_create_data_invalid
* @dataProvider discoveryrule_create_data_valid
*/
public function testDiscoveryRule_Create(array $discoveryrules, $expected_error) {
$result = $this->call('discoveryrule.create', $discoveryrules, $expected_error);
// if ($expected_error !== null) {
// return;
// }
// Accept single and multiple LLD rules just like API method. Work with multi-dimensional array in result.
if (!array_key_exists(0, $discoveryrules)) {
$discoveryrules = zbx_toArray($discoveryrules);
}
if ($expected_error === null) {
foreach ($result['result']['itemids'] as $num => $id) {
$db_discoveryrule = CDBHelper::getRow(
'SELECT i.hostid,i.name,i.key_,i.type,i.delay'.
' FROM items i'.
' WHERE i.itemid='.zbx_dbstr($id)
);
if ($discoveryrules[$num]['type'] === ITEM_TYPE_ZABBIX_ACTIVE && substr($discoveryrules[$num]['key_'], 0, 8) === 'mqtt.get') {
$discoveryrules[$num]['delay'] = CTestArrayHelper::get($discoveryrules[$num], 'delay', '0');
}
$this->assertSame($db_discoveryrule['hostid'], $discoveryrules[$num]['hostid']);
$this->assertSame($db_discoveryrule['name'], $discoveryrules[$num]['name']);
$this->assertSame($db_discoveryrule['key_'], $discoveryrules[$num]['key_']);
$this->assertSame($db_discoveryrule['type'], strval($discoveryrules[$num]['type']));
$this->assertSame($db_discoveryrule['delay'], $discoveryrules[$num]['delay']);
}
}
// TODO: perform advanced checks and other fields.
}
public static function discoveryrule_preprocessing_create_data_invalid() {
$test_data = self::discoveryrule_preprocessing_data_invalid();
$default_options = [
'name' => 'API LLD rule with preprocessing invalid',
'key_' => 'apilldrulewithpreprocessinginvalid',
'hostid' => '50009',
'type' => '0',
'interfaceid' => '50022',
'delay' => '30s'
];
foreach ($test_data as &$test) {
$test['discoveryrule'] += $default_options;
}
unset($test);
return $test_data;
}
public static function discoveryrule_preprocessing_create_data_valid() {
$test_data = self::discoveryrule_preprocessing_data_valid();
$default_options = [
'hostid' => '50009',
'type' => '0',
'interfaceid' => '50022',
'delay' => '30s'
];
$i = 1;
foreach ($test_data as &$test) {
$test['discoveryrule'] += $default_options + [
'name' => 'API LLD rule with preprocessing valid '.$i,
'key_' => 'apilldrulewithpreprocessingvalid'.$i
];
$i++;
}
unset($test);
return $test_data;
}
/**
* @dataProvider discoveryrule_preprocessing_create_data_invalid
* @dataProvider discoveryrule_preprocessing_create_data_valid
*/
public function testDiscoveryRulePreprocessing_Create(array $discoveryrules, $expected_error) {
$result = $this->call('discoveryrule.create', $discoveryrules, $expected_error);
// Accept single and multiple LLD rules just like API method. Work with multi-dimensional array in result.
if (!array_key_exists(0, $discoveryrules)) {
$discoveryrules = zbx_toArray($discoveryrules);
}
if ($expected_error === null) {
foreach ($result['result']['itemids'] as $num => $id) {
if (array_key_exists('preprocessing', $discoveryrules[$num])) {
foreach ($discoveryrules[$num]['preprocessing'] as $idx => $preprocessing) {
// Collect one step at a time. Steps should match the order in which they were given.
$db_preprocessing = CDBHelper::getRow(
'SELECT ip.type,ip.params,ip.error_handler,ip.error_handler_params'.
' FROM item_preproc ip'.
' WHERE ip.itemid='.zbx_dbstr($id).
' AND ip.step='.zbx_dbstr($idx + 1)
);
$this->assertEquals($db_preprocessing['type'], $preprocessing['type']);
$this->assertSame($db_preprocessing['params'], $preprocessing['params']);
$this->assertEquals($db_preprocessing['error_handler'], $preprocessing['error_handler']);
$this->assertSame($db_preprocessing['error_handler_params'],
$preprocessing['error_handler_params']
);
}
}
}
}
// TODO: Create a test to check if preprocessing steps are inherited on host.
}
// TODO: Create API tests for items and item prototypes. It uses the same function to validate pre-processing fields.
public static function discoveryrule_lld_macro_paths_data_invalid() {
return [
'Test incorrect parameter type for lld_macro_paths' => [
'discoveryrule' => [
'lld_macro_paths' => ''
],
'expected_error' => 'Invalid parameter "/1/lld_macro_paths": an array is expected.'
],
'Test incorrect parameter type for lld_macro' => [
'discoveryrule' => [
'lld_macro_paths' => [
[
'lld_macro' => false
]
]
],
'expected_error' => 'Invalid parameter "/1/lld_macro_paths/1/lld_macro": a character string is expected.'
],
'Test incorrect type for lld_macro (multiple macro path index)' => [
'discoveryrule' => [
'lld_macro_paths' => [
[
'lld_macro' => '{#A}',
'path' => '$.list[:1].type'
],
[
'lld_macro' => '{#B}',
'path' => '$.list[:2].type'
],
[
'lld_macro' => false
]
]
],
'expected_error' => 'Invalid parameter "/1/lld_macro_paths/3/lld_macro": a character string is expected.'
],
'Test empty lld_macro' => [
'discoveryrule' => [
'lld_macro_paths' => [
[
'lld_macro' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/lld_macro_paths/1/lld_macro": cannot be empty.'
],
'Test incorrect value for lld_macro' => [
'discoveryrule' => [
'lld_macro_paths' => [
[
'lld_macro' => 'abc'
]
]
],
'expected_error' => 'Invalid parameter "/1/lld_macro_paths/1/lld_macro": a low-level discovery macro is expected.'
],
'Test missing path parameter for lld_macro_paths' => [
'discoveryrule' => [
'lld_macro_paths' => [
[
'lld_macro' => '{#A}'
]
]
],
'expected_error' => 'Invalid parameter "/1/lld_macro_paths/1": the parameter "path" is missing.'
],
'Test incorrect type for path parameter in lld_macro_paths' => [
'discoveryrule' => [
'lld_macro_paths' => [
[
'lld_macro' => '{#A}',
'path' => false
]
]
],
'expected_error' => 'Invalid parameter "/1/lld_macro_paths/1/path": a character string is expected.'
],
'Test empty path parameter in lld_macro_paths' => [
'discoveryrule' => [
'lld_macro_paths' => [
[
'lld_macro' => '{#A}',
'path' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/lld_macro_paths/1/path": cannot be empty.'
],
'Test duplicate lld_macro entries' => [
'discoveryrule' => [
'lld_macro_paths' => [
[
'lld_macro' => '{#A}',
'path' => '$.list[:1].type'
],
[
'lld_macro' => '{#B}',
'path' => '$.list[:2].type'
],
[
'lld_macro' => '{#B}',
'path' => '$.list[:2].type'
]
]
],
'expected_error' => 'Invalid parameter "/1/lld_macro_paths/3": value (lld_macro)=({#B}) already exists.'
],
'Test unexpected parameters lld_macro_paths' => [
'discoveryrule' => [
'lld_macro_paths' => [
[
'lld_macro' => '{#A}',
'path' => '$.list[:1].type',
'param' => 'value'
]
]
],
'expected_error' => 'Invalid parameter "/1/lld_macro_paths/1": unexpected parameter "param".'
]
];
}
public static function discoveryrule_lld_macro_paths_create_data_invalid() {
$test_data = self::discoveryrule_lld_macro_paths_data_invalid();
$default_options = [
'name' => 'API LLD rule with LLD macros invalid',
'key_' => 'apilldrulewithlldmacrosinvalid',
'hostid' => '50009',
'type' => '0',
'interfaceid' => '50022',
'delay' => '30s'
];
foreach ($test_data as &$test) {
$test['discoveryrule'] += $default_options;
}
unset($test);
return $test_data + [
'Test multiple discovery rules and one is broken' => [
'discoveryrule' => [
$default_options + [
'lld_macro_paths' => [
[
'lld_macro' => '{#A}',
'path' => '$.list[:1].type'
]
]
],
[
'name' => 'API LLD rule 6',
'key_' => 'apilldrule6',
'hostid' => '50009',
'type' => '0',
'interfaceid' => '50022',
'delay' => '30s',
'lld_macro_paths' => ''
]
],
'expected_error' => 'Invalid parameter "/2/lld_macro_paths": an array is expected.'
],
'Test no parameters in lld_macro_paths (create)' => [
'discoveryrule' => $default_options + [
'lld_macro_paths' => [[]]
],
'expected_error' => 'Invalid parameter "/1/lld_macro_paths/1": the parameter "lld_macro" is missing.'
]
];
}
public static function discoveryrule_lld_macro_paths_update_data_invalid() {
$test_data = self::discoveryrule_lld_macro_paths_data_invalid();
$default_options = ['itemid' => '110006'];
foreach ($test_data as &$test) {
$test['discoveryrule'] += $default_options;
}
unset($test);
return $test_data + [
'Test incorrect second lld_macro_paths type' => [
'discoveryrule' => [
[
'itemid' => '110006',
'lld_macro_paths' => []
],
[
'itemid' => '110007',
'lld_macro_paths' => ''
]
],
'expected_error' => 'Invalid parameter "/2/lld_macro_paths": an array is expected.'
],
'Test no parameters in lld_macro_paths (update)' => [
'discoveryrule' => $default_options + [
'lld_macro_paths' => [[]]
],
'expected_error' => 'Invalid parameter "/1/lld_macro_paths/1": the parameter "lld_macro" is missing.'
],
'Test unexpected parameter lld_macro_pathid' => [
'discoveryrule' => $default_options + [
'lld_macro_paths' => [
[
'lld_macro_pathid' => '999999'
]
]
],
'expected_error' => 'Invalid parameter "/1/lld_macro_paths/1": unexpected parameter "lld_macro_pathid".'
],
'Test duplicate LLD macro paths entries by giving existing lld_macro' => [
'discoveryrule' => $default_options + [
'lld_macro_paths' => [
[
'lld_macro' => '{#B}',
'path' => '$.list[:2].type'
],
[
'lld_macro' => '{#B}',
'path' => '$.list[:3].type'
]
]
],
'expected_error' => 'Invalid parameter "/1/lld_macro_paths/2": value (lld_macro)=({#B}) already exists.'
],
'Test removal of LLD macro paths on templated discovery rule' => [
'discoveryrule' => [
'itemid' => '110011',
'lld_macro_paths' => []
],
'expected_error' => 'Invalid parameter "/1": cannot update readonly parameter "lld_macro_paths" of inherited object.'
]
];
}
public static function discoveryrule_lld_macro_paths_create_data_valid() {
$default_options = [
'name' => 'API LLD rule with LLD macro paths on a host',
'key_' => 'apilldrulewithlldmacropathsonahost',
'hostid' => '50009',
'type' => '0',
'interfaceid' => '50022',
'delay' => '30s'
];
return [
'Test successful creation of LLD rule with LLD macro paths on a host' => [
'discoveryrule' => $default_options + [
'lld_macro_paths' => [
[
'lld_macro' => '{#A}',
'path' => '$.list[:1].type'
],
[
'lld_macro' => '{#B}',
'path' => '$.list[:2].type'
],
[
'lld_macro' => '{#C}',
'path' => '$.list[:3].type'
]
]
],
'expected_error' => null
],
'Test successful creation of LLD rule with LLD macro paths on a template' => [
'discoveryrule' => [
'name' => 'API LLD rule with LLD macro paths on a template',
'key_' => 'apilldrulewithlldmacropathsonatemplate',
'hostid' => '50010',
'type' => '0',
'delay' => '30s',
'lld_macro_paths' => [
[
'lld_macro' => '{#A}',
'path' => '$.list[:1].type'
],
[
'lld_macro' => '{#B}',
'path' => '$.list[:2].type'
],
[
'lld_macro' => '{#C}',
'path' => '$.list[:3].type'
]
]
],
'expected_error' => null
],
'Test empty lld_macro_paths' => [
'discoveryrule' => [
'name' => 'LLD rule with empty LLD macro paths',
'key_' => 'lld.rule.with.empty.lld.macro.paths',
'hostid' => '50009',
'type' => '0',
'interfaceid' => '50022',
'delay' => '30s',
'lld_macro_paths' => []
],
'expected_error' => null
]
];
}
/**
* @dataProvider discoveryrule_lld_macro_paths_create_data_invalid
* @dataProvider discoveryrule_lld_macro_paths_create_data_valid
*/
public function testDiscoveryRuleLLDMacroPaths_Create(array $discoveryrules, $expected_error) {
$result = $this->call('discoveryrule.create', $discoveryrules, $expected_error);
// Accept single and multiple LLD rules just like API method. Work with multi-dimensional array in result.
if (!array_key_exists(0, $discoveryrules)) {
$discoveryrules = zbx_toArray($discoveryrules);
}
if ($expected_error === null) {
foreach ($result['result']['itemids'] as $num => $id) {
if (array_key_exists('lld_macro_paths', $discoveryrules[$num])) {
// "lld_macro" and "itemid" is a unique combination in the table.
foreach ($discoveryrules[$num]['lld_macro_paths'] as $lld_macro_path) {
$db_lld_macro_path = CDBHelper::getRow(
'SELECT lmp.lld_macro,lmp.path'.
' FROM lld_macro_path lmp'.
' WHERE lmp.itemid='.zbx_dbstr($id).
' AND lmp.lld_macro='.zbx_dbstr($lld_macro_path['lld_macro'])
);
$this->assertSame($db_lld_macro_path['lld_macro'], $lld_macro_path['lld_macro']);
$this->assertSame($db_lld_macro_path['path'], $lld_macro_path['path']);
}
}
}
}
// TODO: Create a test to check if LLD macro paths are inherited on host.
}
// TODO: create a separate test to perform updates on discovery rules and its properties.
public static function discoveryrule_preprocessing_data_invalid() {
// Check preprocessing fields.
return [
'Test incorrect preprocessing type' => [
'discoveryrule' => [
'preprocessing' => ''
],
'expected_error' => 'Invalid parameter "/1/preprocessing": an array is expected.'
],
'Test no preprocessing fields' => [
'discoveryrule' => [
'preprocessing' => [
[]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1": the parameter "type" is missing.'
],
'Test empty preprocessing fields (null)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => null,
'params' => '',
'error_handler' => null,
'error_handler_params' => null
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/type": an integer is expected.'
],
'Test empty preprocessing fields (bool)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => false,
'params' => '',
'error_handler' => null,
'error_handler_params' => null
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/type": an integer is expected.'
],
'Test empty preprocessing fields (string)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => '',
'params' => '',
'error_handler' => null,
'error_handler_params' => null
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/type": an integer is expected.'
],
'Test invalid preprocessing type (array)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => [],
'params' => '',
'error_handler' => null,
'error_handler_params' => null
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/type": an integer is expected.'
],
'Test invalid preprocessing type (string)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => 'abc',
'params' => '',
'error_handler' => '',
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/type": an integer is expected.'
],
'Test invalid preprocessing type (integer)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => 666,
'params' => '',
'error_handler' => '',
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/type": value must be one of 5, 11, 12, 15, 16, 17, 20, 21, 23, 24, 25, 27, 28, 29.'
],
'Test unallowed preprocessing type (integer)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_OCT2DEC,
'params' => '',
'error_handler' => '',
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/type": value must be one of 5, 11, 12, 15, 16, 17, 20, 21, 23, 24, 25, 27, 28, 29.'
],
'Test valid type but empty preprocessing params (bool)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => false,
'error_handler' => '',
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params": a character string is expected.'
],
'Test valid type but empty preprocessing params (string)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => '',
'error_handler' => '',
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params/1": cannot be empty.'
],
'Test valid type but incorrect preprocessing params (array)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => [],
'error_handler' => '',
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params": a character string is expected.'
],
'Test preprocessing params second parameter' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => '^abc$',
'error_handler' => '',
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params": the parameter "2" is missing.'
],
'Test empty preprocessing error handler (null)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^abc$\n123",
'error_handler' => null,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler": an integer is expected.'
],
'Test empty preprocessing error handler (bool)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^abc$\n123",
'error_handler' => false,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler": an integer is expected.'
],
'Test empty preprocessing error handler (string)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^abc$\n123",
'error_handler' => '',
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler": an integer is expected.'
],
'Test incorrect preprocessing error handler (array)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^abc$\n123",
'error_handler' => [],
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler": an integer is expected.'
],
'Test incorrect preprocessing error handler (string)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^abc$\n123",
'error_handler' => 'abc',
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler": an integer is expected.'
],
'Test incorrect preprocessing error handler (integer)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^abc$\n123",
'error_handler' => 666,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler": value must be one of 0, 1, 2, 3.'
],
'Test empty preprocessing error handler params (null)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^abc$\n123",
'error_handler' => ZBX_PREPROC_FAIL_SET_ERROR,
'error_handler_params' => null
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler_params": a character string is expected.'
],
'Test empty preprocessing error handler params (bool)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^abc$\n123",
'error_handler' => ZBX_PREPROC_FAIL_SET_ERROR,
'error_handler_params' => false
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler_params": a character string is expected.'
],
'Test empty preprocessing error handler params (string)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^abc$\n123",
'error_handler' => ZBX_PREPROC_FAIL_SET_ERROR,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler_params": cannot be empty.'
],
'Test incorrect preprocessing error handler params (array)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^abc$\n123",
'error_handler' => ZBX_PREPROC_FAIL_SET_ERROR,
'error_handler_params' => []
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler_params": a character string is expected.'
],
'Test filled preprocessing error handler params (ZBX_PREPROC_REGSUB + ZBX_PREPROC_FAIL_DEFAULT)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^abc$\n123",
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => 'abc'
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler_params": value must be empty.'
],
'Test filled preprocessing error handler params (ZBX_PREPROC_REGSUB + ZBX_PREPROC_FAIL_DISCARD_VALUE)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^abc$\n123",
'error_handler' => ZBX_PREPROC_FAIL_DISCARD_VALUE,
'error_handler_params' => 'abc'
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler_params": value must be empty.'
],
'Test filled preprocessing error handler params (ZBX_PREPROC_JSONPATH + ZBX_PREPROC_FAIL_DEFAULT)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_JSONPATH,
'params' => '$.path.to.node',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => 'Error param'
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler_params": value must be empty.'
],
'Test filled preprocessing error handler params (ZBX_PREPROC_JSONPATH + ZBX_PREPROC_FAIL_DISCARD_VALUE)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_JSONPATH,
'params' => '$.path.to.node',
'error_handler' => ZBX_PREPROC_FAIL_DISCARD_VALUE,
'error_handler_params' => 'Error param'
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler_params": value must be empty.'
],
'Test empty preprocessing error handler params (ZBX_PREPROC_VALIDATE_NOT_REGEX + ZBX_PREPROC_FAIL_SET_ERROR)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_VALIDATE_NOT_REGEX,
'params' => 'abc',
'error_handler' => ZBX_PREPROC_FAIL_SET_ERROR,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler_params": cannot be empty.'
],
'Test filled preprocessing error handler params (ZBX_PREPROC_VALIDATE_NOT_REGEX + ZBX_PREPROC_FAIL_DEFAULT)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_VALIDATE_NOT_REGEX,
'params' => 'abc',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => 'Error param'
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler_params": value must be empty.'
],
'Test filled preprocessing error handler params (ZBX_PREPROC_VALIDATE_NOT_REGEX + ZBX_PREPROC_FAIL_DISCARD_VALUE)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_VALIDATE_NOT_REGEX,
'params' => 'abc',
'error_handler' => ZBX_PREPROC_FAIL_DISCARD_VALUE,
'error_handler_params' => 'Error param'
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler_params": value must be empty.'
],
'Test filled preprocessing error handler params (ZBX_PREPROC_ERROR_FIELD_JSON + ZBX_PREPROC_FAIL_DEFAULT)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_ERROR_FIELD_JSON,
'params' => 'abc',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => 'Error param'
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler_params": value must be empty.'
],
'Test incorrect preprocessing params for type ZBX_PREPROC_THROTTLE_TIMED_VALUE' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_THROTTLE_TIMED_VALUE,
'params' => 'abc',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params/1": a time unit is expected.'
],
'Test unallowed preprocessing error handler (ZBX_PREPROC_THROTTLE_TIMED_VALUE + ZBX_PREPROC_FAIL_DISCARD_VALUE)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_THROTTLE_TIMED_VALUE,
'params' => '{#MACRO}',
'error_handler' => ZBX_PREPROC_FAIL_DISCARD_VALUE,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params/1": a time unit is expected.'
],
'Test unallowed preprocessing error handler (ZBX_PREPROC_THROTTLE_TIMED_VALUE + ZBX_PREPROC_FAIL_SET_VALUE)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_THROTTLE_TIMED_VALUE,
'params' => '{#MACRO}',
'error_handler' => ZBX_PREPROC_FAIL_SET_VALUE,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params/1": a time unit is expected.'
],
'Test unallowed preprocessing error handler (ZBX_PREPROC_THROTTLE_TIMED_VALUE + ZBX_PREPROC_FAIL_SET_ERROR)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_THROTTLE_TIMED_VALUE,
'params' => '1h',
'error_handler' => ZBX_PREPROC_FAIL_SET_ERROR,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler": value must be 0.'
],
'Test two preprocessing steps for type ZBX_PREPROC_THROTTLE_TIMED_VALUE' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_THROTTLE_TIMED_VALUE,
'params' => '1h',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
],
[
'type' => ZBX_PREPROC_THROTTLE_TIMED_VALUE,
'params' => '1h',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/2": only one object can exist within the combinations of (type)=((19, 20)).'
],
'Test filled preprocessing error handler params (ZBX_PREPROC_PROMETHEUS_TO_JSON + ZBX_PREPROC_FAIL_DEFAULT)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_PROMETHEUS_TO_JSON,
'params' => 'wmi_service_state{name="dhcp",state="running"} == 1',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => 'Error param'
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler_params": value must be empty.'
],
'Test filled preprocessing error handler params (ZBX_PREPROC_PROMETHEUS_TO_JSON + ZBX_PREPROC_FAIL_DISCARD_VALUE)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_PROMETHEUS_TO_JSON,
'params' => 'wmi_service_state{name="dhcp",state="running"} == 1',
'error_handler' => ZBX_PREPROC_FAIL_DISCARD_VALUE,
'error_handler_params' => 'Error param'
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/error_handler_params": value must be empty.'
],
'Test two preprocessing steps for type ZBX_PREPROC_PROMETHEUS_TO_JSON' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_PROMETHEUS_TO_JSON,
'params' => 'wmi_service_state{name="dhcp",state="running"} == 1',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
],
[
'type' => ZBX_PREPROC_PROMETHEUS_TO_JSON,
'params' => 'wmi_service_state{name="dhcp",state="running"} == 1',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/2": only one object can exist within the combinations of (type)=((22, 23)).'
],
'Test empty preprocessing parameters for ZBX_PREPROC_CSV_TO_JSON type' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_CSV_TO_JSON,
'params' => '',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params": the parameter "2" is missing.'
],
'Test invalid (false) preprocessing parameters for ZBX_PREPROC_CSV_TO_JSON type' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_CSV_TO_JSON,
'params' => false,
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params": a character string is expected.'
],
'Test invalid (array) preprocessing parameters for ZBX_PREPROC_CSV_TO_JSON type' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_CSV_TO_JSON,
'params' => [],
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params": a character string is expected.'
],
'Test invalid (too many) preprocessing parameters for ZBX_PREPROC_CSV_TO_JSON type' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_CSV_TO_JSON,
'params' => "\n\n\n",
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params": unexpected parameter "4".'
],
'Test missing third preprocessing parameter for ZBX_PREPROC_CSV_TO_JSON type' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_CSV_TO_JSON,
'params' => "\n",
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params": the parameter "3" is missing.'
],
'Test first preprocessing parameter (too long) for ZBX_PREPROC_CSV_TO_JSON type' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_CSV_TO_JSON,
'params' => "xx\n\n1",
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params/1": value is too long.'
],
'Test second preprocessing parameter (too long) for ZBX_PREPROC_CSV_TO_JSON type' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_CSV_TO_JSON,
'params' => ",\nyy\n1",
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params/2": value is too long.'
],
'Test third preprocessing parameter (non-integer) for ZBX_PREPROC_CSV_TO_JSON type' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_CSV_TO_JSON,
'params' => "\n\n",
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params/3": an integer is expected.'
],
'Test third preprocessing parameter (incorrect value) for ZBX_PREPROC_CSV_TO_JSON type' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_CSV_TO_JSON,
'params' => "\n\n2",
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params/3": value must be one of '.implode(', ', [ZBX_PREPROC_CSV_NO_HEADER, ZBX_PREPROC_CSV_HEADER]).'.'
],
'Test non-empty preprocessing parameters for ZBX_PREPROC_XML_TO_JSON type' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_XML_TO_JSON,
'params' => 'abc',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1/params": value must be empty.'
]
];
}
public static function discoveryrule_preprocessing_data_valid() {
return [
'Test two valid preprocessing steps (same)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_VALIDATE_NOT_REGEX,
'params' => 'abc',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
],
[
'type' => ZBX_PREPROC_VALIDATE_NOT_REGEX,
'params' => 'def',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => null
],
'Test two valid preprocessing steps (different)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_VALIDATE_NOT_REGEX,
'params' => 'abc',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
],
[
'type' => ZBX_PREPROC_JSONPATH,
'params' => '$.path.to.node',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => null
],
'Test valid preprocessing (ZBX_PREPROC_REGSUB + ZBX_PREPROC_FAIL_SET_ERROR)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^abc\n123$",
'error_handler' => ZBX_PREPROC_FAIL_SET_ERROR,
'error_handler_params' => 'Error param'
]
]
],
'expected_error' => null
],
'Test valid preprocessing (ZBX_PREPROC_JSONPATH + ZBX_PREPROC_FAIL_DISCARD_VALUE)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_JSONPATH,
'params' => '$.path.to.node',
'error_handler' => ZBX_PREPROC_FAIL_DISCARD_VALUE,
'error_handler_params' => ''
]
]
],
'expected_error' => null
],
'Test valid preprocessing (ZBX_PREPROC_JSONPATH + ZBX_PREPROC_FAIL_SET_VALUE)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_JSONPATH,
'params' => '$.path.to.node',
'error_handler' => ZBX_PREPROC_FAIL_SET_VALUE,
'error_handler_params' => ''
]
]
],
'expected_error' => null
],
'Test valid preprocessing (ZBX_PREPROC_JSONPATH + ZBX_PREPROC_FAIL_DEFAULT)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_JSONPATH,
'params' => '$.path.to.node',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => null
],
'Test valid preprocessing (ZBX_PREPROC_VALIDATE_NOT_REGEX + ZBX_PREPROC_FAIL_DEFAULT)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_VALIDATE_NOT_REGEX,
'params' => 'abc',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => null
],
'Test valid preprocessing (ZBX_PREPROC_ERROR_FIELD_JSON + ZBX_PREPROC_FAIL_DEFAULT)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_ERROR_FIELD_JSON,
'params' => 'abc',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => null
],
'Test valid preprocessing (ZBX_PREPROC_ERROR_FIELD_JSON + ZBX_PREPROC_FAIL_DISCARD_VALUE)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_ERROR_FIELD_JSON,
'params' => 'abc',
'error_handler' => ZBX_PREPROC_FAIL_DISCARD_VALUE,
'error_handler_params' => ''
]
]
],
'expected_error' => null
],
'Test valid preprocessing (ZBX_PREPROC_ERROR_FIELD_JSON + ZBX_PREPROC_FAIL_SET_VALUE)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_ERROR_FIELD_JSON,
'params' => 'abc',
'error_handler' => ZBX_PREPROC_FAIL_SET_VALUE,
'error_handler_params' => 'abc'
]
]
],
'expected_error' => null
],
'Test valid preprocessing (ZBX_PREPROC_ERROR_FIELD_JSON + ZBX_PREPROC_FAIL_SET_ERROR)' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_ERROR_FIELD_JSON,
'params' => 'abc',
'error_handler' => ZBX_PREPROC_FAIL_SET_ERROR,
'error_handler_params' => 'abc'
]
]
],
'expected_error' => null
],
'Test valid preprocessing with user macro for type ZBX_PREPROC_THROTTLE_TIMED_VALUE' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_THROTTLE_TIMED_VALUE,
'params' => '{$MACRO}',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => null
],
'Test valid preprocessing with LLD macro for type ZBX_PREPROC_THROTTLE_TIMED_VALUE' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_THROTTLE_TIMED_VALUE,
'params' => '{$MACRO}',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => null
],
'Test valid preprocessing with time unit for type ZBX_PREPROC_THROTTLE_TIMED_VALUE' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_THROTTLE_TIMED_VALUE,
'params' => '1h',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => null
],
'Test valid preprocessing with type ZBX_PREPROC_PROMETHEUS_TO_JSON' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_PROMETHEUS_TO_JSON,
'params' => 'wmi_service_state{name="dhcp",state="running"} == 1',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => null
],
'Test valid empty preprocessing' => [
'discoveryrule' => [
'preprocessing' => []
],
'expected_error' => null
],
'Test valid preprocessing with type ZBX_PREPROC_CSV_TO_JSON having empty first two parameters' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_CSV_TO_JSON,
'params' => "\n\n1",
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => null
],
'Test valid preprocessing with type ZBX_PREPROC_CSV_TO_JSON having empty first parameter' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_CSV_TO_JSON,
'params' => "\ny\n1",
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => null
],
'Test valid preprocessing with type ZBX_PREPROC_CSV_TO_JSON having empty second parameter' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_CSV_TO_JSON,
'params' => "x\n\n1",
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => null
],
'Test valid preprocessing with type ZBX_PREPROC_CSV_TO_JSON having all parameters' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_CSV_TO_JSON,
'params' => ",\n\"\n0",
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => null
],
'Test valid preprocessing with type ZBX_PREPROC_XML_TO_JSON having empty parameters' => [
'discoveryrule' => [
'preprocessing' => [
[
'type' => ZBX_PREPROC_XML_TO_JSON,
'params' => '',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => null
]
];
}
public static function discoveryrule_preprocessing_update_data_invalid() {
$test_data = self::discoveryrule_preprocessing_data_invalid();
$default_options = ['itemid' => '110006'];
foreach ($test_data as &$test) {
$test['discoveryrule'] += $default_options;
}
unset($test);
return $test_data + [
'Test individual preprocessing step update with only one parameter' => [
'discoveryrule' => $default_options + [
'preprocessing' => [
[
'item_preprocid' => '5716',
'params' => '2h'
]
]
],
'expected_error' => 'Invalid parameter "/1/preprocessing/1": unexpected parameter "item_preprocid".'
],
'Test templated discovery rule preprocessing step update' => [
'discoveryrule' => [
'itemid' => '110011',
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^abc\n123$",
'error_handler' => ZBX_PREPROC_FAIL_SET_ERROR,
'error_handler_params' => 'Error param'
]
]
],
'expected_error' => 'Invalid parameter "/1": cannot update readonly parameter "preprocessing" of inherited object.'
]
];
}
public static function discoveryrule_preprocessing_update_data_valid() {
$test_data = self::discoveryrule_preprocessing_data_valid();
$default_options = ['itemid' => '110006'];
foreach ($test_data as &$test) {
$test['discoveryrule'] += $default_options;
}
unset($test);
return [
'Test replacing preprocessing steps' => [
'discoveryrule' => $default_options + [
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^jkl$\n123",
'error_handler' => ZBX_PREPROC_FAIL_SET_ERROR,
'error_handler_params' => 'error'
],
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^def$\n123",
'error_handler' => ZBX_PREPROC_FAIL_DISCARD_VALUE,
'error_handler_params' => ''
],
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^ghi$\n123",
'error_handler' => ZBX_PREPROC_FAIL_SET_VALUE,
'error_handler_params' => 'xxx'
],
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^abc\n123$",
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => null
]
] + $test_data + [
'Test valid update by adding new preprocessing steps' => [
'discoveryrule' => [
'itemid' => '110009',
'preprocessing' => [
[
'type' => ZBX_PREPROC_THROTTLE_TIMED_VALUE,
'params' => '1h',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
]
]
],
'expected_error' => null
]
];
}
/**
* @dataProvider discoveryrule_preprocessing_update_data_invalid
* @dataProvider discoveryrule_preprocessing_update_data_valid
*/
public function testDiscoveryRulePreprocessing_Update($discoveryrules, $expected_error) {
if ($expected_error === null) {
// Before updating, collect old data for given discovery rules.
$itemids = [];
if (array_key_exists(0, $discoveryrules)) {
foreach ($discoveryrules as $discoveryrule) {
$itemids[$discoveryrule['itemid']] = true;
}
}
else {
$itemids[$discoveryrules['itemid']] = true;
}
$db_preprocessing = CDBHelper::getAll(
'SELECT ip.item_preprocid,ip.itemid,ip.step,i.templateid,ip.type,ip.params,ip.error_handler,'.
'ip.error_handler_params'.
' FROM item_preproc ip,items i'.
' WHERE '.dbConditionId('ip.itemid', array_keys($itemids)).
' AND ip.itemid=i.itemid'.
' ORDER BY ip.itemid ASC,ip.step ASC'
);
$this->call('discoveryrule.update', $discoveryrules, $expected_error);
$db_upd_preprocessing = CDBHelper::getAll(
'SELECT ip.item_preprocid,ip.itemid,ip.step,i.templateid,ip.type,ip.params,ip.error_handler,'.
'ip.error_handler_params'.
' FROM item_preproc ip,items i'.
' WHERE '.dbConditionId('ip.itemid', array_keys($itemids)).
' AND ip.itemid=i.itemid'.
' ORDER BY ip.itemid ASC,ip.step ASC'
);
// Accept single and multiple LLD rules just like API method. Work with multi-dimensional array in result.
if (!array_key_exists(0, $discoveryrules)) {
$discoveryrules = zbx_toArray($discoveryrules);
}
// Compare records from DB before and after API call.
foreach ($discoveryrules as $discoveryrule) {
$old_preprocessing = [];
$new_preprocessing = [];
if ($db_preprocessing) {
foreach ($db_preprocessing as $db_preproc_step) {
$itemid = $db_preproc_step['itemid'];
if (bccomp($itemid, $discoveryrule['itemid']) == 0) {
$old_preprocessing[$itemid][$db_preproc_step['step']] = $db_preproc_step;
}
}
}
if ($db_upd_preprocessing) {
foreach ($db_upd_preprocessing as $db_upd_preproc_step) {
$itemid = $db_upd_preproc_step['itemid'];
if (bccomp($itemid, $discoveryrule['itemid']) == 0) {
$new_preprocessing[$itemid][$db_upd_preproc_step['step']] = $db_upd_preproc_step;
}
}
}
// If new pre-processing steps are set.
if (array_key_exists('preprocessing', $discoveryrule)) {
if ($discoveryrule['preprocessing']) {
foreach ($discoveryrule['preprocessing'] as $num => $preprocessing_step) {
if ($old_preprocessing) {
$old_preproc_step = $old_preprocessing[$discoveryrule['itemid']][$num + 1];
if ($old_preproc_step['templateid'] == 0) {
// If not templated discovery rule, it's allowed to change steps.
$this->assertNotEmpty($new_preprocessing);
// New steps must exist.
$new_preproc_step = $new_preprocessing[$discoveryrule['itemid']][$num + 1];
$this->assertEquals($preprocessing_step['type'], $new_preproc_step['type']);
$this->assertSame($preprocessing_step['params'], $new_preproc_step['params']);
$this->assertEquals($preprocessing_step['error_handler'],
$new_preproc_step['error_handler']
);
$this->assertSame($preprocessing_step['error_handler_params'],
$new_preproc_step['error_handler_params']
);
}
else {
// Pre-processing steps for templated discovery rule should stay the same.
$this->assertSame($old_preprocessing, $new_preprocessing);
}
}
else {
/*
* If this is not a templated discovery rule, check if there are steps created and check
* each step.
*/
$this->assertNotEmpty($new_preprocessing);
// New steps must exist.
$new_preproc_step = $new_preprocessing[$discoveryrule['itemid']][$num + 1];
$this->assertEquals($preprocessing_step['type'], $new_preproc_step['type']);
$this->assertSame($preprocessing_step['params'], $new_preproc_step['params']);
$this->assertEquals($preprocessing_step['error_handler'],
$new_preproc_step['error_handler']
);
$this->assertSame($preprocessing_step['error_handler_params'],
$new_preproc_step['error_handler_params']
);
}
}
}
else {
// No steps are set, so old records should be cleared.
$this->assertEmpty($new_preprocessing);
}
}
else {
// No new pre-processing steps are set, so nothing should change at all. Arrays should be the same.
$this->assertSame($old_preprocessing, $new_preprocessing);
}
}
}
else {
// Call method and make sure it really returns the error.
$this->call('discoveryrule.update', $discoveryrules, $expected_error);
}
}
public static function discoveryrule_lld_macro_paths_update_data_valid() {
return [
'Test successful clearing of records for lld_macro_paths on host' => [
'discoveryrule' => [
'itemid' => '110008',
'lld_macro_paths' => []
],
'expected_error' => null
],
'Test successful clearing of records for lld_macro_paths on template' => [
'discoveryrule' => [
'itemid' => '110010',
'lld_macro_paths' => []
],
'expected_error' => null
],
'Test successful update by not changing existing records' => [
'discoveryrule' => [
'itemid' => '110007',
'lld_macro_paths' => [
[
'lld_macro' => '{#A}',
'path' => '$.list[:1].type'
],
[
'lld_macro' => '{#B}',
'path' => '$.list[:2].type'
],
[
'lld_macro' => '{#C}',
'path' => '$.list[:3].type'
]
]
],
'expected_error' => null
],
'Test successful update of lld_macro and path for existing records' => [
'discoveryrule' => [
'itemid' => '110007',
'lld_macro_paths' => [
[
'lld_macro' => '{#X}',
'path' => '$.list[:9].type'
],
[
'lld_macro' => '{#Y}',
'path' => '$.list[:10].type'
],
[
'lld_macro' => '{#Z}',
'path' => '$.list[:11].type'
]
]
],
'expected_error' => null
],
'Test successful update of lld_macro_paths by adding new records' => [
'discoveryrule' => [
'itemid' => '110007',
'lld_macro_paths' => [
[
'lld_macro' => '{#X}',
'path' => '$.list[:9].type'
],
[
'lld_macro' => '{#Y}',
'path' => '$.list[:10].type'
],
[
'lld_macro' => '{#Z}',
'path' => '$.list[:11].type'
],
[
'lld_macro' => '{#Q}',
'path' => '$.list[:13].type'
]
]
],
'expected_error' => null
],
'Test successful update of lld_macro_paths by replaceing them with exact values' => [
'discoveryrule' => [
'itemid' => '110006',
'lld_macro_paths' => [
[
'lld_macro' => '{#A}',
'path' => '$.list[:1].type'
],
[
'lld_macro' => '{#B}',
'path' => '$.list[:2].type'
],
[
'lld_macro' => '{#C}',
'path' => '$.list[:3].type'
],
[
'lld_macro' => '{#D}',
'path' => '$.list[:4].type'
],
[
'lld_macro' => '{#E}',
'path' => '$.list[:5].type'
]
]
],
'expected_error' => null
],
'Test successful update of lld_macro_paths by replacing only one with new value and leaving rest the same' => [
'discoveryrule' => [
'itemid' => '110006',
'lld_macro_paths' => [
[
'lld_macro' => '{#A}',
'path' => '$.list[:1].type'
],
[
'lld_macro' => '{#B}',
'path' => '$.list[:2].type'
],
[
'lld_macro' => '{#C}',
'path' => '$.list[:3].type'
],
[
'lld_macro' => '{#D}',
'path' => '$.list[:4].type'
],
[
'lld_macro' => '{#Z}',
'path' => '$.list[:10].type'
]
]
],
'expected_error' => null
],
'Test successful update of lld_macro_paths by replace only one record with new path' => [
'discoveryrule' => [
'itemid' => '110006',
'lld_macro_paths' => [
[
'lld_macro' => '{#A}',
'path' => '$.list[:1].type'
],
[
'lld_macro' => '{#B}',
'path' => '$.list[:2].type'
],
[
'lld_macro' => '{#C}',
'path' => '$.list[:3].type'
],
[
'lld_macro' => '{#D}',
'path' => '$.list[:4].type'
],
[
'lld_macro' => '{#E}',
'path' => '$.list[:10].type'
]
]
],
'expected_error' => null
],
'Test successful update of lld_macro_paths by deleting one record' => [
'discoveryrule' => [
'itemid' => '110006',
'lld_macro_paths' => [
[
'lld_macro' => '{#A}',
'path' => '$.list[:1].type'
],
[
'lld_macro' => '{#B}',
'path' => '$.list[:2].type'
],
[
'lld_macro' => '{#C}',
'path' => '$.list[:3].type'
],
[
'lld_macro' => '{#D}',
'path' => '$.list[:4].type'
]
]
],
'expected_error' => null
]
];
}
/**
* @dataProvider discoveryrule_lld_macro_paths_update_data_invalid
* @dataProvider discoveryrule_lld_macro_paths_update_data_valid
*/
public function testDiscoveryRuleLLDMacroPaths_Update($discoveryrules, $expected_error) {
if ($expected_error !== null) {
$this->call('discoveryrule.update', $discoveryrules, $expected_error);
return;
}
// Accept single and multiple LLD rules just like API method. Work with multi-dimensional array in result.
if (!array_key_exists(0, $discoveryrules)) {
$discoveryrules = zbx_toArray($discoveryrules);
}
// Before updating, collect old data for given discovery rules.
$itemids = [];
foreach ($discoveryrules as $discoveryrule) {
$itemids[$discoveryrule['itemid']] = true;
}
$db_paths = CDBHelper::getAll(
'SELECT lmp.lld_macro_pathid,lmp.itemid,lmp.lld_macro,lmp.path'.
' FROM lld_macro_path lmp'.
' WHERE '.dbConditionId('lmp.itemid', array_keys($itemids)).
' ORDER BY lmp.lld_macro_pathid ASC'
);
$db_paths_old = [];
foreach ($db_paths as $db_path) {
$db_paths_old[$db_path['itemid']][$db_path['lld_macro']] = $db_path;
}
$this->call('discoveryrule.update', $discoveryrules, $expected_error);
$db_paths = CDBHelper::getAll(
'SELECT lmp.lld_macro_pathid,lmp.itemid,lmp.lld_macro,lmp.path'.
' FROM lld_macro_path lmp'.
' WHERE '.dbConditionId('lmp.itemid', array_keys($itemids)).
' ORDER BY lmp.lld_macro_pathid ASC'
);
$db_paths_new = [];
foreach ($db_paths as $db_path) {
$db_paths_new[$db_path['itemid']][$db_path['lld_macro']] = $db_path;
}
// Compare records from DB before and after API call.
foreach ($discoveryrules as $discoveryrule) {
foreach ($discoveryrule['lld_macro_paths'] as $lld_macro_path) {
$this->assertArrayHasKey($discoveryrule['itemid'], $db_paths_new);
$this->assertArrayHasKey($lld_macro_path['lld_macro'], $db_paths_new[$discoveryrule['itemid']]);
$db_lld_macro_path = $db_paths_new[$discoveryrule['itemid']][$lld_macro_path['lld_macro']];
if (array_key_exists($discoveryrule['itemid'], $db_paths_old)
&& array_key_exists($lld_macro_path['lld_macro'], $db_paths_old[$discoveryrule['itemid']])) {
$this->assertSame(
$db_paths_old[$discoveryrule['itemid']][$lld_macro_path['lld_macro']]['lld_macro_pathid'],
$db_lld_macro_path['lld_macro_pathid']
);
unset($db_paths_old[$discoveryrule['itemid']][$lld_macro_path['lld_macro']]);
}
$this->assertSame($lld_macro_path['path'], $db_lld_macro_path['path']);
}
if ($discoveryrule['lld_macro_paths']) {
if (array_key_exists($discoveryrule['itemid'], $db_paths_old)) {
foreach ($db_paths_old[$discoveryrule['itemid']] as $lld_macro => $foo) {
$this->assertArrayNotHasKey($lld_macro, $db_paths_new[$discoveryrule['itemid']]);
}
}
}
else {
$this->assertArrayNotHasKey($discoveryrule['itemid'], $db_paths_new);
}
}
}
public static function discoveryrule_get_data_invalid() {
return [
'Test getting non-existing LLD rule' => [
'discoveryrule' => [
'itemids' => '123456'
],
'get_result' => [
],
'expected_error' => 'No permissions to referred object or it does not exist!'
]
];
// TODO: add other discovery rule properties.
}
public static function discoveryrule_get_data_valid() {
return [
'Test getting existing LLD rule' => [
'discoveryrule' => [
'output' => ['itemid'],
'itemids' => ['110006']
],
'get_result' => [
'itemid' => '110006'
],
'expected_error' => null
]
];
// TODO: add other discovery rule properties.
}
/**
* @dataProvider discoveryrule_get_data_invalid
* @dataProvider discoveryrule_get_data_valid
*/
public function testDiscoveryRule_Get($discoveryrule, $get_result, $expected_error) {
// TODO: fill this test with more fields to check.
$result = $this->call('discoveryrule.get', $discoveryrule);
if ($expected_error === null) {
foreach ($result['result'] as $entry) {
$this->assertSame($entry['itemid'], $get_result['itemid']);
}
}
else {
$this->assertSame($result['result'], $get_result);
}
}
public static function discoveryrule_lld_macro_paths_get_data_valid() {
$itemid = '110012';
return [
'Test getting lld_macro and path' => [
'discoveryrule' => [
'output' => ['itemid'],
'itemids' => [$itemid],
'selectLLDMacroPaths' => ['lld_macro', 'path']
],
'expected_result' => [
'itemid' => $itemid,
'lld_macro_paths' => [
[
'lld_macro' => '{#A}',
'path' => '$.list[:1].type'
],
[
'lld_macro' => '{#B}',
'path' => '$.list[:2].type'
],
[
'lld_macro' => '{#C}',
'path' => '$.list[:3].type'
],
[
'lld_macro' => '{#D}',
'path' => '$.list[:4].type'
],
[
'lld_macro' => '{#E}',
'path' => '$.list[:5].type'
]
]
],
'expected_error' => null
],
'Test getting lld_macro and path' => [
'discoveryrule' => [
'output' => ['itemid'],
'itemids' => [$itemid],
'selectLLDMacroPaths' => ['lld_macro', 'path']
],
'expected_result' => [
'itemid' => $itemid,
'lld_macro_paths' => [
[
'lld_macro' => '{#A}',
'path' => '$.list[:1].type'
],
[
'lld_macro' => '{#B}',
'path' => '$.list[:2].type'
],
[
'lld_macro' => '{#C}',
'path' => '$.list[:3].type'
],
[
'lld_macro' => '{#D}',
'path' => '$.list[:4].type'
],
[
'lld_macro' => '{#E}',
'path' => '$.list[:5].type'
]
]
],
'expected_error' => null
],
'Test getting all LLD macro path fields' => [
'discoveryrule' => [
'output' => ['itemid'],
'itemids' => [$itemid],
'selectLLDMacroPaths' => 'extend'
],
'expected_result' => [
'itemid' => $itemid,
'lld_macro_paths' => [
[
'lld_macro' => '{#A}',
'path' => '$.list[:1].type'
],
[
'lld_macro' => '{#B}',
'path' => '$.list[:2].type'
],
[
'lld_macro' => '{#C}',
'path' => '$.list[:3].type'
],
[
'lld_macro' => '{#D}',
'path' => '$.list[:4].type'
],
[
'lld_macro' => '{#E}',
'path' => '$.list[:5].type'
]
]
],
'expected_error' => null
]
];
}
/**
* @dataProvider discoveryrule_lld_macro_paths_get_data_valid
*/
public function testDiscoveryRuleLLDMacroPaths_Get($discoveryrule, $expected_result, $expected_error) {
$result = $this->call('discoveryrule.get', $discoveryrule);
if ($expected_error === null) {
foreach ($result['result'] as $entry) {
$this->assertSame($expected_result['itemid'], $entry['itemid']);
// Check related objects.
if (array_key_exists('selectLLDMacroPaths', $discoveryrule)) {
$this->assertArrayHasKey('lld_macro_paths', $entry);
CTestArrayHelper::usort($entry['lld_macro_paths'], ['lld_macro']);
$this->assertSame($expected_result['lld_macro_paths'], $entry['lld_macro_paths']);
}
else {
$this->assertArrayNotHasKey('lld_macro_paths', $entry);
}
}
}
else {
$this->assertSame($result['result'], $expected_result);
}
}
public static function discoveryrule_preprocessing_get_data_valid() {
return [
'Test getting type, params, error_handler and error_handler_params from preprocessing' => [
'discoveryrule' => [
'output' => ['itemid'],
'itemids' => ['110013'],
'selectPreprocessing' => ['type', 'params', 'error_handler', 'error_handler_params']
],
'get_result' => [
'itemid' => '110013',
'preprocessing' => [
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^abc$\n123",
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
],
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^def$\n123",
'error_handler' => ZBX_PREPROC_FAIL_DISCARD_VALUE,
'error_handler_params' => ''
],
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^ghi$\n123",
'error_handler' => ZBX_PREPROC_FAIL_SET_VALUE,
'error_handler_params' => 'xxx'
],
[
'type' => ZBX_PREPROC_REGSUB,
'params' => "^jkl$\n123",
'error_handler' => ZBX_PREPROC_FAIL_SET_ERROR,
'error_handler_params' => 'error'
]
]
],
'expected_error' => null
],
'Test getting params from preprocessing' => [
'discoveryrule' => [
'output' => ['itemid'],
'itemids' => ['110010'],
'selectPreprocessing' => ['params']
],
'get_result' => [
'itemid' => '110010',
'preprocessing' => [
[
'params' => '$.path.to.node1'
],
[
'params' => '$.path.to.node2'
],
[
'params' => '$.path.to.node3'
],
[
'params' => '$.path.to.node4'
]
]
],
'expected_error' => null
],
'Test getting all preprocessing fields' => [
'discoveryrule' => [
'output' => ['itemid'],
'itemids' => ['110011'],
'selectPreprocessing' => 'extend'
],
'get_result' => [
'itemid' => '110011',
'preprocessing' => [
[
'type' => ZBX_PREPROC_JSONPATH,
'params' => '$.path.to.node1',
'error_handler' => ZBX_PREPROC_FAIL_DEFAULT,
'error_handler_params' => ''
],
[
'type' => ZBX_PREPROC_JSONPATH,
'params' => '$.path.to.node2',
'error_handler' => ZBX_PREPROC_FAIL_DISCARD_VALUE,
'error_handler_params' => ''
],
[
'type' => ZBX_PREPROC_JSONPATH,
'params' => '$.path.to.node3',
'error_handler' => ZBX_PREPROC_FAIL_SET_VALUE,
'error_handler_params' => 'xxx'
],
[
'type' => ZBX_PREPROC_JSONPATH,
'params' => '$.path.to.node4',
'error_handler' => ZBX_PREPROC_FAIL_SET_ERROR,
'error_handler_params' => 'error'
]
]
],
'expected_error' => null
]
];
}
/**
* @dataProvider discoveryrule_preprocessing_get_data_valid
*/
public function testDiscoveryRulePreprocessing_Get($discoveryrule, $get_result, $expected_error) {
$result = $this->call('discoveryrule.get', $discoveryrule);
if ($expected_error === null) {
foreach ($result['result'] as $entry) {
$this->assertSame($entry['itemid'], $get_result['itemid']);
// Check related objects.
if (array_key_exists('selectPreprocessing', $discoveryrule)) {
$this->assertArrayHasKey('preprocessing', $get_result);
if (array_key_exists('preprocessing', $get_result)) {
$this->assertEquals($entry['preprocessing'], $get_result['preprocessing']);
}
}
else {
$this->assertArrayNotHasKey('preprocessing', $get_result);
}
}
}
else {
$this->assertSame($result['result'], $get_result);
}
}
public static function discoveryrule_copy_data_invalid() {
return [
'Test no discoveryids given when copying LLD rule' => [
'params' => [
'hostids' => ['50009']
],
'expected_error' => 'No discovery rule IDs given.'
],
'Test empty discoveryids when copying LLD rule' => [
'params' => [
'discoveryids' => '',
'hostids' => ['50009']
],
'expected_error' => 'No discovery rule IDs given.'
],
'Test incorrect discoveryids type when copying LLD rule' => [
'params' => [
'discoveryids' => [],
'hostids' => ['50009']
],
'expected_error' => 'No discovery rule IDs given.'
],
'Test no hostids given when copying LLD rule' => [
'params' => [
'discoveryids' => ['110006']
],
'expected_error' => 'No host IDs given.'
],
'Test empty hostids when copying LLD rule' => [
'params' => [
'discoveryids' => ['110006'],
'hostids' => ''
],
'expected_error' => 'No host IDs given.'
],
'Test incorrect hostids type when copying LLD rule' => [
'params' => [
'discoveryids' => ['110006'],
'hostids' => []
],
'expected_error' => 'No host IDs given.'
],
'Test copying on same host or when destination host already has that key' => [
'params' => [
'discoveryids' => ['110006'],
'hostids' => ['50009']
],
'expected_error' => 'An LLD rule with key "apilldrule1" already exists on the host "API Host".'
],
'Test copying on non-existing host' => [
'params' => [
'discoveryids' => ['110006'],
'hostids' => ['1']
],
'expected_error' => 'No permissions to referred object or it does not exist!'
],
'Test copying a non-existing LLD rule' => [
'params' => [
'discoveryids' => ['1'],
'hostids' => ['50012']
],
'expected_error' => 'No permissions to referred object or it does not exist!'
],
'Test copying LLD rule to a template' => [
'params' => [
'discoveryids' => ['110006'],
'hostids' => ['50010']
],
'expected_error' => 'Cannot find host interface on "API Template" for item key "apilldrule1".'
],
'Test duplicate hosts in request' => [
'params' => [
'discoveryids' => ['110006'],
'hostids' => ['50012', '50012']
],
'expected_error' => 'An LLD rule with key "apilldrule1" already exists on the host "API Host for read permissions".'
],
'Test duplicate LLD rules in request' => [
'params' => [
'discoveryids' => ['110006', '110006'],
'hostids' => ['50012']
],
'expected_error' => 'No permissions to referred object or it does not exist!'
// TODO: Error is very strange and API should be checked for bugs.
],
'Test LLD dependent on master which does not exists on destination host.' => [
'params' => [
// test.discovery.rule.1:dependent.lld.3
'discoveryids' => ['2605'],
// test.discovery.rule.2
'hostids' => ['1018']
],
'expected_error' => 'Discovery rule "dependent.lld.3" cannot be copied without its master item.'
],
'Test LLD dependent on master having max dependency levels.' => [
'params' => [
// test.discovery.rule.1:dependent.lld.1
'discoveryids' => ['2601'],
// test.discovery.rule.2
'hostids' => ['1018']
],
'expected_error' => 'Cannot set dependency for LLD rule with key "dependent.lld.1" on the master item with key "item.1.1.1.1" on the host "test.discovery.rule.host.2": allowed count of dependency levels would be exceeded.'
]
];
}
public static function discoveryrule_copy_data_valid() {
return [
'Test successful LLD rule copy to two hosts' => [
'params' => [
'discoveryids' => ['110006'],
'hostids' => ['50012', '50013']
],
'expected_error' => null
],
'Test copy LLD dependent to host having master item with same key_' => [
'params' => [
// test.discovery.rule.1:dependent.lld.2
'discoveryids' => ['2603'],
// test.discovery.rule.2
'hostids' => ['1018']
],
'expected_error' => null
]
];
}
/**
* @dataProvider discoveryrule_copy_data_invalid
* @dataProvider discoveryrule_copy_data_valid
*/
public function testDiscoveryRule_Copy($params, $expected_error) {
$result = $this->call('discoveryrule.copy', $params, $expected_error);
if ($expected_error === null) {
$this->assertTrue($result['result']);
// Get all discovery rule fields.
$src_items = CDBHelper::getAll(
'SELECT i.type,i.snmp_oid,i.name,i.key_,i.delay,'.
'i.status,i.value_type,i.trapper_hosts,i.units,i.logtimefmt,i.valuemapid,'.
'i.params,i.ipmi_sensor,i.authtype,i.username,i.password,i.publickey,i.privatekey,'.
'i.flags,i.description,i.inventory_link,i.lifetime,i.jmx_endpoint,i.url,i.query_fields,i.timeout,'.
'i.posts,i.status_codes,i.follow_redirects,i.post_type,i.http_proxy,i.headers,i.retrieve_mode,'.
'i.request_method,i.ssl_cert_file,i.ssl_key_file,i.ssl_key_password,i.verify_peer,'.
'i.verify_host,i.allow_traps'.
' FROM items i'.
' WHERE '.dbConditionId('i.itemid', $params['discoveryids'])
);
$src_items = zbx_toHash($src_items, 'key_');
/*
* NOTE: Metadata like lastlogsize, mtime should not be copied. Fields like hostid, interfaceid, itemid
* are not selected, since they will be different.
*/
// Find same items on destination hosts.
foreach ($params['discoveryids'] as $itemid) {
$dst_items = CDBHelper::getAll(
'SELECT src.type,src.snmp_oid,src.name,src.key_,'.
'src.delay,src.status,src.value_type,src.trapper_hosts,src.units,'.
'src.logtimefmt,src.valuemapid,src.params,'.
'src.ipmi_sensor,src.authtype,src.username,src.password,src.publickey,src.privatekey,'.
'src.flags,src.description,src.inventory_link,src.lifetime,src.jmx_endpoint,'.
'src.url,src.query_fields,src.timeout,src.posts,src.status_codes,src.follow_redirects,'.
'src.post_type,src.http_proxy,src.headers,src.retrieve_mode,src.request_method,'.
'src.ssl_cert_file,src.ssl_key_file,src.ssl_key_password,src.verify_peer,src.verify_host,'.
'src.allow_traps'.
' FROM items src,items dest'.
' WHERE dest.itemid='.zbx_dbstr($itemid).
' AND src.key_=dest.key_'.
' AND '.dbConditionInt('src.hostid', $params['hostids'])
);
foreach ($dst_items as $dst_item) {
$this->assertSame($src_items[$dst_item['key_']], $dst_item);
}
}
}
}
public static function discoveryrule_lld_macro_paths_copy_data_valid() {
return [
'Test successful LLD rule with macro paths copy to two hosts' => [
'params' => [
'discoveryids' => ['110012'],
'hostids' => ['50012', '50013']
],
'expected_error' => null
]
];
}
/**
* @dataProvider discoveryrule_copy_data_invalid
* @dataProvider discoveryrule_lld_macro_paths_copy_data_valid
*/
public function testDiscoveryRuleLLDMacroPaths_Copy($params, $expected_error) {
$result = $this->call('discoveryrule.copy', $params, $expected_error);
if ($expected_error === null) {
$this->assertTrue($result['result']);
// Get discovery rule and LLD macro path fields.
$src_lld_macro_paths = CDBHelper::getAll(
'SELECT lmp.lld_macro,lmp.path,i.key_'.
' FROM lld_macro_path lmp,items i'.
' WHERE i.itemid=lmp.itemid'.
' AND '.dbConditionId('i.itemid', $params['discoveryids'])
);
$src = [];
foreach ($src_lld_macro_paths as $src_lld_macro_path) {
$src[$src_lld_macro_path['key_']][] = $src_lld_macro_path;
}
// Find same items on destination hosts.
foreach ($params['discoveryids'] as $itemid) {
$dst_lld_macro_paths = CDBHelper::getAll(
'SELECT lmp.lld_macro,lmp.path,src.key_,src.hostid'.
' FROM lld_macro_path lmp,items src,items dest'.
' WHERE dest.itemid='.zbx_dbstr($itemid).
' AND src.key_=dest.key_'.
' AND lmp.itemid=dest.itemid'.
' AND '.dbConditionInt('src.hostid', $params['hostids'])
);
$dst = [];
foreach ($dst_lld_macro_paths as $dst_lld_macro_path) {
$dst[$dst_lld_macro_path['hostid']][$dst_lld_macro_path['key_']][] = $dst_lld_macro_path;
}
foreach ($dst as $discoveryrules) {
foreach ($discoveryrules as $key => $lld_macro_paths) {
foreach ($lld_macro_paths as &$lld_macro_path) {
unset($lld_macro_path['hostid']);
}
unset($lld_macro_path);
$this->assertSame($src[$key], $lld_macro_paths);
}
}
}
}
}
public static function discoveryrule_preprocessing_copy_data_valid() {
return [
'Test successful LLD rule with preprocessing copy to two hosts' => [
'params' => [
'discoveryids' => ['110013'],
'hostids' => ['50012', '50013']
],
'expected_error' => null
]
];
}
/**
* @dataProvider discoveryrule_copy_data_invalid
* @dataProvider discoveryrule_preprocessing_copy_data_valid
*/
public function testDiscoveryRulePreprocessing_Copy($params, $expected_error) {
$result = $this->call('discoveryrule.copy', $params, $expected_error);
if ($expected_error === null) {
$this->assertTrue($result['result']);
// Get discovery rule and pre-processing fields.
$src_preprocessing = CDBHelper::getAll(
'SELECT ip.step,ip.type,ip.params,ip.error_handler,ip.error_handler_params,i.key_'.
' FROM item_preproc ip,items i'.
' WHERE i.itemid=ip.itemid'.
' AND '.dbConditionId('i.itemid', $params['discoveryids'])
);
$src = [];
foreach ($src_preprocessing as $src_preproc_step) {
$src[$src_preproc_step['key_']][$src_preproc_step['step']] = $src_preproc_step;
}
// Find same items on destination hosts.
foreach ($params['discoveryids'] as $itemid) {
$dst_preprocessing = CDBHelper::getAll(
'SELECT ip.step,ip.type,ip.params,ip.error_handler,ip.error_handler_params,src.key_,src.hostid'.
' FROM item_preproc ip,items src,items dest'.
' WHERE dest.itemid='.zbx_dbstr($itemid).
' AND src.key_=dest.key_'.
' AND ip.itemid=dest.itemid'.
' AND '.dbConditionInt('src.hostid', $params['hostids'])
);
$dst = [];
foreach ($dst_preprocessing as $dst_preproc_step) {
$dst[$dst_preproc_step['hostid']][$dst_preproc_step['key_']][$dst_preproc_step['step']] =
$dst_preproc_step;
}
foreach ($dst as $discoveryrules) {
foreach ($discoveryrules as $key => $preprocessing) {
foreach ($preprocessing as &$preprocessing_step) {
unset($preprocessing_step['hostid']);
}
unset($preprocessing_step);
$this->assertSame($src[$key], $preprocessing);
}
}
}
}
}
public static function discoveryrule_preprocessing_delete_data() {
return [
'Test successful delete of LLD rule and preprocessing data' => [
'discoveryrule' => [
'110006'
],
'expected_error' => null
]
];
// TODO: add templated discovery rules.
}
/**
* @dataProvider discoveryrule_preprocessing_delete_data
*/
public function testDiscoveryRulePreprocessing_Delete($discoveryrule, $expected_error) {
$result = $this->call('discoveryrule.delete', $discoveryrule, $expected_error);
if ($expected_error === null) {
foreach ($result['result']['ruleids'] as $id) {
$this->assertEquals(0, CDBHelper::getCount(
'SELECT i.itemid FROM items i WHERE i.itemid='.zbx_dbstr($id)
));
// Check related tables - preprocessing.
$this->assertEquals(0, CDBHelper::getCount(
'SELECT ip.item_preprocid'.
' FROM item_preproc ip'.
' WHERE ip.itemid='.zbx_dbstr($id)
));
}
}
// TODO: add templated discovery rules and check on errors.
}
public static function discoveryrule_lld_macro_paths_delete_data() {
return [
'Test successful delete of LLD rule and LLD macro paths' => [
'discoveryrule' => [
'110009'
],
'expected_error' => null
]
];
// TODO: add templated discovery rules.
}
/**
* @dataProvider discoveryrule_lld_macro_paths_delete_data
*/
public function testDiscoveryRuleLLDMacroPaths_Delete($discoveryrule, $expected_error) {
$result = $this->call('discoveryrule.delete', $discoveryrule, $expected_error);
if ($expected_error === null) {
foreach ($result['result']['ruleids'] as $id) {
$this->assertEquals(0, CDBHelper::getCount(
'SELECT i.itemid FROM items i WHERE i.itemid='.zbx_dbstr($id)
));
// Check related tables - LLD macro paths.
$this->assertEquals(0, CDBHelper::getCount(
'SELECT lmp.lld_macro_pathid'.
' FROM lld_macro_path lmp'.
' WHERE lmp.itemid='.zbx_dbstr($id)
));
}
}
// TODO: add templated discovery rules and check on errors.
}
public static function discoveryrule_overrides_delete_data() {
return [
'Test cannot delete nothing.' => [
[],
[],
[],
'Invalid parameter "/": cannot be empty.'
],
'Test cannot delete what does not exist.' => [
['9999999999'],
[],
[],
'No permissions to referred object or it does not exist!'
],
'Test overrides and override operations are deleted.' => [
['133763'],
['10001', '10002'],
['10001', '10002', '10003', '10004', '10005', '10006'],
null
]
];
}
/**
* @dataProvider discoveryrule_overrides_delete_data
*/
public function testDiscoveryRuleOverrides_Delete(array $itemids, array $overrideids, array $operationids, $error) {
$result = $this->call('discoveryrule.delete', $itemids, $error);
if ($error === null) {
$this->assertEquals($result['result']['ruleids'], $itemids);
$db_lld_overrides = CDBHelper::getAll('SELECT * from lld_override WHERE '.
dbConditionId('lld_overrideid', $overrideids)
);
$this->assertEmpty($db_lld_overrides);
$lld_override_conditions = CDBHelper::getAll('SELECT * from lld_override_condition WHERE '.
dbConditionId('lld_overrideid', $overrideids)
);
$this->assertEmpty($lld_override_conditions);
$lld_override_operations = CDBHelper::getAll('SELECT * from lld_override_operation WHERE '.
dbConditionId('lld_overrideid', $overrideids)
);
$this->assertEmpty($lld_override_operations);
$lld_override_opdiscover = CDBHelper::getAll('SELECT * from lld_override_opdiscover WHERE '.
dbConditionId('lld_override_operationid', $operationids)
);
$this->assertEmpty($lld_override_opdiscover);
$lld_override_opstatus = CDBHelper::getAll('SELECT * from lld_override_opstatus WHERE '.
dbConditionId('lld_override_operationid', $operationids)
);
$this->assertEmpty($lld_override_opstatus);
$lld_override_ophistory = CDBHelper::getAll('SELECT * from lld_override_ophistory WHERE '.
dbConditionId('lld_override_operationid', $operationids)
);
$this->assertEmpty($lld_override_ophistory);
$lld_override_opinventory = CDBHelper::getAll('SELECT * from lld_override_opinventory WHERE '.
dbConditionId('lld_override_operationid', $operationids)
);
$this->assertEmpty($lld_override_opinventory);
$lld_override_opperiod = CDBHelper::getAll('SELECT * from lld_override_opperiod WHERE '.
dbConditionId('lld_override_operationid', $operationids)
);
$this->assertEmpty($lld_override_opperiod);
$lld_override_opseverity = CDBHelper::getAll('SELECT * from lld_override_opseverity WHERE '.
dbConditionId('lld_override_operationid', $operationids)
);
$this->assertEmpty($lld_override_opseverity);
$lld_override_optag = CDBHelper::getAll('SELECT * from lld_override_optag WHERE '.
dbConditionId('lld_override_operationid', $operationids)
);
$this->assertEmpty($lld_override_optag);
$lld_override_optemplate = CDBHelper::getAll('SELECT * from lld_override_optemplate WHERE '.
dbConditionId('lld_override_operationid', $operationids)
);
$this->assertEmpty($lld_override_optemplate);
$lld_override_optrends = CDBHelper::getAll('SELECT * from lld_override_optrends WHERE '.
dbConditionId('lld_override_operationid', $operationids)
);
$this->assertEmpty($lld_override_optrends);
}
}
public static function discoveryrule_overrides_create_data_invalid() {
$num = 0;
$new_lld_overrides = function(array $overrides) use (&$num) {
return [
'name' => 'Overrides (invalid)',
'key_' => 'invalid.lld.with.overrides.'.($num ++),
'hostid' => '50009',
'type' => ITEM_TYPE_TRAPPER,
'overrides' => $overrides
];
};
return [
// LLD rule overrides
'Test /1/overrides/2/name is mandatory.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 2
],
[
'step' => 1
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/2": the parameter "name" is missing.'
],
'Test /1/overrides/2/step must be numeric.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 'A'
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/step": an integer is expected.'
],
'Test /1/overrides/2/step is mandatory.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 2
],
[
'name' => 'override 2'
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/2": the parameter "step" is missing.'
],
'Test /1/overrides/2/step must be unique.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 2
],
[
'name' => 'override 2',
'step' => 2
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/2": value (step)=(2) already exists.'
],
'Test /1/overrides/2/name must be unique.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 4
],
[
'name' => 'override',
'step' => 2
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/2": value (name)=(override) already exists.'
],
'Test /1/overrides/1/stop field is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'stop' => 2
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/stop": value must be one of '.implode(', ', [ZBX_LLD_OVERRIDE_STOP_NO, ZBX_LLD_OVERRIDE_STOP_YES]).'.'
],
// LLD rule override filter
'Test /1/overrides/1/filter/evaltype is mandatory.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => []
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/filter": the parameter "evaltype" is missing.'
],
'Test /1/overrides/1/filter/evaltype is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => 4
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/filter/evaltype": value must be one of '.implode(', ', [CONDITION_EVAL_TYPE_AND_OR, CONDITION_EVAL_TYPE_AND, CONDITION_EVAL_TYPE_OR, CONDITION_EVAL_TYPE_EXPRESSION]).'.'
],
'Test /1/overrides/1/filter/formula is required if /1/overrides/1/filter/evaltype == 3 (custom expression).' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_EXPRESSION,
'conditions' => [
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'value' => ''
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/filter": the parameter "formula" is missing.'
],
'Test /1/overrides/1/filter/formula cannot be empty.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_EXPRESSION,
'formula' => '',
'conditions' => [
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'value' => ''
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/filter/formula": cannot be empty.'
],
'Test /1/overrides/1/filter/formula cannot be incorrect.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_EXPRESSION,
'formula' => 'x',
'conditions' => [
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'value' => ''
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/filter/formula": incorrect syntax near "x".'
],
'Test /1/overrides/1/filter/formula refers to undefined condition (missing formulaid field).' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_EXPRESSION,
'formula' => 'B or A',
'conditions' => [
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'value' => ''
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/filter/conditions/1": the parameter "formulaid" is missing.'
],
'Test /1/overrides/1/filter/formula refers to undefined condition (missing another condition).' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_EXPRESSION,
'formula' => 'B or A',
'conditions' => [
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'value' => '',
'formulaid' => 'B'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/filter/formula": missing filter condition "A".'
],
'Test /1/overrides/1/filter/eval_formula is read_only.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_EXPRESSION,
'eval_formula' => 'A',
'formula' => 'A',
'conditions' => [
[
'macro' => '{#CORRECT}',
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'value' => '',
'formulaid' => 'A'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/filter": unexpected parameter "eval_formula".'
],
// LLD rule override filter conditions
'Test /1/overrides/1/filter/formula field is mandatory.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_EXPRESSION
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/filter": the parameter "formula" is missing.'
],
'Test /1/overrides/1/filter/conditions/1/macro field is mandatory.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_AND_OR,
'conditions' => [
[]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/filter/conditions/1": the parameter "macro" is missing.'
],
'Test /1/overrides/1/filter/conditions/1/macro is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_EXPRESSION,
'formula' => 'A',
'conditions' => [
[
'macro' => '{##INCORRECT}',
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'value' => '',
'formulaid' => 'A'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/filter/conditions/1/macro": a low-level discovery macro is expected.'
],
'Test /1/overrides/1/filter/conditions/1/value is mandatory.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_AND_OR,
'conditions' => [
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_NOT_REGEXP
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/filter/conditions/1": the parameter "value" is missing.'
],
'Test /1/overrides/1/filter/conditions/1/operator type is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_AND_OR,
'conditions' => [
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_YES
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/filter/conditions/1/operator": value must be one of '.implode(', ', [CONDITION_OPERATOR_REGEXP, CONDITION_OPERATOR_NOT_REGEXP, CONDITION_OPERATOR_EXISTS, CONDITION_OPERATOR_NOT_EXISTS]).'.'
],
// LLD rule override operation
'Test /1/overrides/1/operations/1/operationobject type is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => 4
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/operationobject": value must be one of '.implode(', ', [OPERATION_OBJECT_ITEM_PROTOTYPE, OPERATION_OBJECT_TRIGGER_PROTOTYPE, OPERATION_OBJECT_GRAPH_PROTOTYPE, OPERATION_OBJECT_HOST_PROTOTYPE]).'.'
],
'Test /1/overrides/1/operations/1/operator type is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_YES
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/operator": value must be one of '.implode(', ', [CONDITION_OPERATOR_EQUAL, CONDITION_OPERATOR_NOT_EQUAL, CONDITION_OPERATOR_LIKE, CONDITION_OPERATOR_NOT_LIKE, CONDITION_OPERATOR_REGEXP, CONDITION_OPERATOR_NOT_REGEXP]).'.'
],
// LLD rule override operation status
'Test /1/overrides/1/operations/1/opstatus/status is mandatory.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opstatus' => []
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opstatus": the parameter "status" is missing.'
],
'Test /1/overrides/1/operations/1/opstatus/status is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opstatus' => [
'status' => 2
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opstatus/status": value must be one of '.implode(', ', [ZBX_PROTOTYPE_STATUS_ENABLED, ZBX_PROTOTYPE_STATUS_DISABLED]).'.'
],
'Test /1/overrides/1/operations/1/opstatus is not supported for graph prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_GRAPH_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_ENABLED
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opstatus": should be empty.'
],
// LLD rule override operation discover
'Test /1/overrides/1/operations/1/opdiscover/discover is mandatory.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opdiscover' => []
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opdiscover": the parameter "discover" is missing.'
],
'Test /1/overrides/1/operations/1/opdiscover/discover is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opdiscover' => [
'discover' => 2
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opdiscover/discover": value must be one of '.implode(', ', [ZBX_PROTOTYPE_DISCOVER, ZBX_PROTOTYPE_NO_DISCOVER]).'.'
],
// LLD rule override operation period
'Test /1/overrides/1/operations/1/opperiod/delay is mandatory.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opperiod' => []
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opperiod": the parameter "delay" is missing.'
],
'Test /1/overrides/1/operations/1/opperiod/delay is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opperiod' => [
'delay' => 'www'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opperiod/delay": a time unit is expected.'
],
'Test /1/overrides/1/operations/1/opperiod/delay cannot be 0.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opperiod' => [
'delay' => '0'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opperiod/delay": cannot be equal to zero without custom intervals.'
],
'Test /1/overrides/1/operations/1/opperiod/delay has to be correct update interval.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opperiod' => [
'delay' => '2w'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opperiod/delay": value must be one of 0-86400.'
],
'Test /1/overrides/1/operations/1/opperiod/delay has to be correct flexible interval.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opperiod' => [
'delay' => '0;0/1,00:00-23:00'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opperiod/delay": must have at least one interval greater than 0.'
],
'Test /1/overrides/1/operations/1/opperiod is not supported for trigger prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_TRIGGER_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opperiod' => [
'delay' => '1d'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opperiod": should be empty.'
],
'Test /1/overrides/1/operations/1/opperiod is not supported for graph prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_GRAPH_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opperiod' => [
'delay' => '1d'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opperiod": should be empty.'
],
'Test /1/overrides/1/operations/1/opperiod is not supported for host prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opperiod' => [
'delay' => '1d'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opperiod": should be empty.'
],
// LLD rule override operation history
'Test /1/overrides/1/operations/1/ophistory/history is mandatory.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'ophistory' => []
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/ophistory": the parameter "history" is missing.'
],
'Test /1/overrides/1/operations/1/ophistory/history is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'ophistory' => [
'history' => 'www'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/ophistory/history": a time unit is expected.'
],
'Test /1/overrides/1/operations/1/ophistory/history max value is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'ophistory' => [
'history' => 25 * SEC_PER_YEAR + 1
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/ophistory/history": value must be one of 0, '.SEC_PER_HOUR.'-'.(25 * SEC_PER_YEAR).'.'
],
'Test /1/overrides/1/operations/1/ophistory/history min value is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'ophistory' => [
'history' => SEC_PER_HOUR - 1
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/ophistory/history": value must be one of 0, '.SEC_PER_HOUR.'-'.(25 * SEC_PER_YEAR).'.'
],
'Test /1/overrides/1/operations/1/ophistory is not supported for trigger prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_TRIGGER_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'ophistory' => [
'history' => '1d'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/ophistory": should be empty.'
],
'Test /1/overrides/1/operations/1/ophistory is not supported for graph prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_GRAPH_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'ophistory' => [
'history' => '1d'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/ophistory": should be empty.'
],
'Test /1/overrides/1/operations/1/ophistory is not supported for host prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'ophistory' => [
'history' => '1d'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/ophistory": should be empty.'
],
// LLD rule override operation trends
'Test /1/overrides/1/operations/1/optrends/trends is mandatory.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optrends' => []
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optrends": the parameter "trends" is missing.'
],
'Test /1/overrides/1/operations/1/optrends/trends is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optrends' => [
'trends' => 'www'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optrends/trends": a time unit is expected.'
],
'Test /1/overrides/1/operations/1/optrends/trends max value is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optrends' => [
'trends' => 25 * SEC_PER_YEAR + 1
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optrends/trends": value must be one of 0, '.SEC_PER_DAY.'-'.(25 * SEC_PER_YEAR).'.'
],
'Test /1/overrides/1/operations/1/optrends/trends min value is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optrends' => [
'trends' => SEC_PER_DAY - 1
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optrends/trends": value must be one of 0, '.SEC_PER_DAY.'-'.(25 * SEC_PER_YEAR).'.'
],
'Test /1/overrides/1/operations/1/optrends is not supported for trigger prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_TRIGGER_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optrends' => [
'trends' => '1d'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optrends": should be empty.'
],
'Test /1/overrides/1/operations/1/optrends is not supported for graph prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_GRAPH_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optrends' => [
'trends' => '1d'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optrends": should be empty.'
],
'Test /1/overrides/1/operations/1/optrends is not supported for host prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optrends' => [
'trends' => '1d'
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optrends": should be empty.'
],
// LLD rule override operation severity
'Test /1/overrides/1/operations/1/opseverity/severity is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opseverity' => [
'severity' => 999
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opseverity": should be empty.'
],
'Test /1/overrides/1/operations/1/opseverity is not supported for item prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opseverity' => [
'severity' => TRIGGER_SEVERITY_INFORMATION
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opseverity": should be empty.'
],
'Test /1/overrides/1/operations/1/opseverity is not supported for graph prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_GRAPH_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opseverity' => [
'severity' => TRIGGER_SEVERITY_WARNING
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opseverity": should be empty.'
],
'Test /1/overrides/1/operations/1/opseverity is not supported for host prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opseverity' => [
'severity' => TRIGGER_SEVERITY_WARNING
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opseverity": should be empty.'
],
// LLD rule override operation tag
'Test /1/overrides/1/operations/1/optag/1/tag is mandatory.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optag' => [
[]
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optag/1": the parameter "tag" is missing.'
],
'Test /1/overrides/1/operations/1/optag/1/tag cannot be empty.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optag' => [
[
'tag' => ''
]
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optag/1/tag": cannot be empty.'
],
'Test /1/overrides/1/operations/1/optag is not supported for graph prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_GRAPH_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optag' => [
['tag' => 'www']
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optag": should be empty.'
],
// LLD rule override operation template
'Test /1/overrides/1/operations/1/optemplate/1/templateid is mandatory.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optemplate' => [
[]
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optemplate/1": the parameter "templateid" is missing.'
],
'Test /1/overrides/1/operations/1/optemplate/1/templateid type is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optemplate' => [
[
'templateid' => ''
]
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optemplate/1/templateid": a number is expected.'
],
'Test /1/overrides/1/operations/1/optemplate/1/templateid must exist.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optemplate' => [
[
'templateid' => '1'
]
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optemplate/1/templateid": a template ID is expected.'
],
'Test /1/overrides/1/operations/1/optemplate/1/templateid cannot exist twice.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optemplate' => [
[
'templateid' => '50010'
],
[
'templateid' => '50010'
]
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optemplate/2": value (templateid)=(50010) already exists.'
],
'Test /1/overrides/1/operations/1/optemplate is not supported for item prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optemplate' => [
['template' => '1']
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optemplate": should be empty.'
],
'Test /1/overrides/1/operations/1/optemplate is not supported for trigger prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_TRIGGER_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optemplate' => [
['template' => '1']
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optemplate": should be empty.'
],
'Test /1/overrides/1/operations/1/optemplate is not supported for graph prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_GRAPH_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'optemplate' => [
['template' => '1']
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/optemplate": should be empty.'
],
// LLD rule override operation inventory
'Test /1/overrides/1/operations/1/opinventory/inventory_mode is mandatory.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opinventory' => []
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opinventory": the parameter "inventory_mode" is missing.'
],
'Test /1/overrides/1/operations/1/opinventory/inventory_mode is validated.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opinventory' => [
'inventory_mode' => -2
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opinventory/inventory_mode": value must be one of '.implode(', ', [HOST_INVENTORY_DISABLED, HOST_INVENTORY_MANUAL, HOST_INVENTORY_AUTOMATIC]).'.'
],
'Test /1/overrides/1/operations/1/opinventory is not supported for item prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opinventory' => [
'inventory_mode' => HOST_INVENTORY_MANUAL
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opinventory": should be empty.'
],
'Test /1/overrides/1/operations/1/opinventory is not supported for trigger prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_TRIGGER_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opinventory' => [
'inventory_mode' => HOST_INVENTORY_MANUAL
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opinventory": should be empty.'
],
'Test /1/overrides/1/operations/1/opinventory is not supported for graph prototype object.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_GRAPH_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opinventory' => [
'inventory_mode' => HOST_INVENTORY_MANUAL
]
]
]
]
])
],
'expected_error' => 'Invalid parameter "/1/overrides/1/operations/1/opinventory": should be empty.'
]
];
}
public static function discoveryrule_overrides_create_data_valid() {
$num = 0;
$new_lld_overrides = function(array $overrides) use (&$num) {
return [
'name' => 'Overrides (valid)',
'key_' => 'valid.lld.with.overrides.'.($num ++),
'hostid' => '50009',
'type' => ITEM_TYPE_TRAPPER,
'overrides' => $overrides
];
};
$data = [
// LLD rule overrides
'Test /1/overrides/1/filter and /1/overrides/1/operations are not mandatory.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override 1',
'step' => 2
]
])
],
'expected_error' => null
],
'Test /1/overrides/1/operations can be empty.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override 1',
'step' => 2,
'operations' => []
]
])
],
'expected_error' => null
],
'Test /1/overrides/1/stop default value is set correctly.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override 1',
'step' => 2
],
[
'name' => 'override 2',
'step' => 3,
'stop' => ZBX_LLD_OVERRIDE_STOP_NO
],
[
'name' => 'override 3',
'step' => 1,
'stop' => ZBX_LLD_OVERRIDE_STOP_YES
]
])
],
'expected_error' => null
],
// LLD rule override filter
'Test /1/overrides/1/filter/evaltype with three conditions where two are unique.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_AND_OR,
'conditions' => [
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'value' => ''
],
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_REGEXP,
'value' => ''
],
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_REGEXP,
'value' => ''
]
]
]
]
])
],
'expected_error' => null
],
// LLD rule override filter condition
'Test /1/overrides/1/filter/conditions/3/operator default value is set correctly.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_EXPRESSION,
'formula' => 'B or A or C',
'conditions' => [
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'value' => '',
'formulaid' => 'B'
],
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_REGEXP,
'value' => '',
'formulaid' => 'C'
],
[
'macro' => '{#MACRO}',
'value' => '',
'formulaid' => 'A'
]
]
]
]
])
],
'expected_error' => null
],
'Test /1/overrides/1/filter/conditions/3/operator default value is set correctly (field ordering issue #2).' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_EXPRESSION,
'formula' => 'B or A or C',
'conditions' => [
[
'macro' => '{#MACRO}',
'value' => '',
'formulaid' => 'B'
],
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_REGEXP,
'value' => '',
'formulaid' => 'C'
],
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'value' => '',
'formulaid' => 'A'
]
]
]
]
])
],
'expected_error' => null
],
'Test /1/overrides/1/filter/conditions/3/operator default value is set correctly (field ordering issue #3).' => [
'discoveryrules' => [
$new_lld_overrides([
[
'step' => 1,
'name' => 'override',
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_EXPRESSION,
'formula' => 'B or A or C',
'conditions' => [
[
'macro' => '{#MACRO}',
'value' => '',
'formulaid' => 'B',
'operator' => CONDITION_OPERATOR_REGEXP
],
[
'operator' => CONDITION_OPERATOR_REGEXP,
'macro' => '{#MACRO}',
'value' => '',
'formulaid' => 'C'
],
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'value' => '',
'formulaid' => 'A'
]
]
]
]
])
],
'expected_error' => null
],
'Test /1/overrides/1/filter/formula is set correctly if ./evaltype is custom_expression.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_EXPRESSION,
'formula' => 'B or (A or C)',
'conditions' => [
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'value' => '',
'formulaid' => 'B'
],
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_REGEXP,
'value' => '',
'formulaid' => 'C'
],
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_REGEXP,
'value' => '',
'formulaid' => 'A'
]
]
]
]
])
],
'expected_error' => null
],
'Test /1/overrides/1/filter/formula and formulaid of conditions can pass with default values if ./evaltype is not custom_expression.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_OR,
'formula' => '',
'conditions' => [
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'value' => '',
'formulaid' => ''
],
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_REGEXP,
'value' => '',
'formulaid' => ''
],
[
'macro' => '{#MACRO}',
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'value' => '',
'formulaid' => ''
]
]
]
]
])
],
'expected_error' => null
],
// LLD rule override operation
'Test /1/overrides/1/operations ./operator and ./value defaults are set.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_ENABLED
]
]
]
]
])
],
'expected_error' => null
],
'Test /1/overrides/1/operations two similar operations can be set.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_REGEXP,
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_ENABLED
]
],
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_LIKE,
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_ENABLED
]
]
]
]
])
],
'expected_error' => null
],
'Test /1/overrides/1/operations (ordering issue #2).' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_ENABLED
]
],
[
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_ENABLED
],
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_LIKE
]
]
]
])
],
'expected_error' => null
],
'Test /1/overrides/1/operations/1/ all operation objects are set correctly for item_prototype.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_DISABLED
],
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_DISCOVER
],
'opperiod' => [
'delay' => '1d'
],
'ophistory' => [
'history' => '1d'
],
'optrends' => [
'trends' => '1d'
]
]
]
]
])
],
'expected_error' => null
],
'Test /1/overrides/1/operations/1/ all operation objects are set correctly for item_prototype.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_TRIGGER_PROTOTYPE,
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_DISABLED
],
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_DISCOVER
],
'opseverity' => [
'severity' => TRIGGER_SEVERITY_WARNING
],
'optag' => [
[
'tag' => 'tag',
'value' => 'tag value'
],
[
'tag' => 'tag 2'
]
]
]
]
]
])
],
'expected_error' => null
],
'Test /1/overrides/1/operations/1/ all operation objects are set correctly for graph_prototype.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_GRAPH_PROTOTYPE,
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_NO_DISCOVER
]
]
]
]
])
],
'expected_error' => null
],
'Test /1/overrides/1/operations/1/ all operation objects are set correctly for host_prototype.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_DISABLED
],
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_DISCOVER
],
'optemplate' => [
[
'templateid' => '50010'
]
],
'optag' => [
[
'tag' => 'tag1',
'value' => 'value1'
],
[
'tag' => 'tag2',
'value' => 'value2'
]
],
'opinventory' => [
'inventory_mode' => HOST_INVENTORY_AUTOMATIC
]
]
]
]
])
],
'expected_error' => null
],
'Test /1/overrides/1/operations/ multiple operations are set correctly.' => [
'discoveryrules' => [
$new_lld_overrides([
[
'name' => 'override',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_DISABLED
],
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_DISCOVER
],
'opperiod' => [
'delay' => '1d'
],
'ophistory' => [
'history' => '1d'
],
'optrends' => [
'trends' => '1d'
]
],
[
'operationobject' => OPERATION_OBJECT_TRIGGER_PROTOTYPE,
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_DISABLED
],
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_DISCOVER
],
'opseverity' => [
'severity' => TRIGGER_SEVERITY_WARNING
],
'optag' => [
[
'tag' => 'tag',
'value' => 'tag value'
],
[
'tag' => 'tag 2'
]
]
],
[
'operationobject' => OPERATION_OBJECT_GRAPH_PROTOTYPE,
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_NO_DISCOVER
]
],
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_DISABLED
],
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_DISCOVER
],
'optemplate' => [
[
'templateid' => '50010'
]
],
'optag' => [
[
'tag' => 'tag1',
'value' => 'value1'
],
[
'tag' => 'tag2',
'value' => 'value2'
]
],
'opinventory' => [
'inventory_mode' => HOST_INVENTORY_AUTOMATIC
]
]
]
]
])
],
'expected_error' => null
]
];
return $data;
}
/**
* @dataProvider discoveryrule_overrides_create_data_invalid
* @dataProvider discoveryrule_overrides_create_data_valid
*/
public function testDiscoveryRuleOverrides_Create(array $request, $expected_error) {
$result = $this->call('discoveryrule.create', $request, $expected_error);
if ($expected_error === null) {
foreach ($result['result']['itemids'] as $num => $itemid) {
$db_lld_overrides = CDBHelper::getAll('SELECT * from lld_override WHERE '.
dbConditionId('itemid', (array) $itemid)
);
$request_lld_overrides = $request[$num]['overrides'];
foreach ($request_lld_overrides as $override_num => $request_lld_override) {
$this->assertLLDOverride($db_lld_overrides[$override_num], $request_lld_override);
}
}
}
}
/**
* @param array $db_lld_override Table "lld_override" row (all fields).
* @param array $db_lld_override['lld_overrideid']
* @param array $db_lld_override['itemid']
* @param array $db_lld_override['name']
* @param array $db_lld_override['step']
* @param array $db_lld_override['evaltype']
* @param array $db_lld_override['formula']
* @param array $db_lld_override['stop']
* @param array $request_lld_override
* @param array $request_lld_override['name']
* @param array $request_lld_override['step']
* @param array $request_lld_override['stop'] (optional)
* @param array $request_lld_override['filter'] (optional)
* @param array $request_lld_override['operations'] (optional)
*/
private function assertLLDOverride(array $db_lld_override, array $request_lld_override) {
$this->assertEquals($db_lld_override['name'], $request_lld_override['name']);
$this->assertEquals($db_lld_override['step'], $request_lld_override['step'], 'Override step value.');
$stop = array_key_exists('stop', $request_lld_override)
? $request_lld_override['stop']
: ZBX_LLD_OVERRIDE_STOP_NO;
$this->assertEquals($db_lld_override['stop'], $stop, 'Override stop value.');
if (array_key_exists('filter', $request_lld_override)) {
$this->assertLLDOverrideFilter($db_lld_override, $request_lld_override['filter']);
}
else {
$this->assertEmpty($db_lld_override['formula']);
$this->assertEquals($db_lld_override['evaltype'], CONDITION_EVAL_TYPE_AND_OR);
}
$db_lld_operations_count = CDBHelper::getCount('SELECT * from lld_override_operation WHERE '.
dbConditionId('lld_overrideid', (array) $db_lld_override['lld_overrideid'])
);
if (array_key_exists('operations', $request_lld_override)) {
$this->assertEquals(count($request_lld_override['operations']), $db_lld_operations_count,
'Expected count of operations.'
);
foreach ($request_lld_override['operations'] as $num => $operation) {
$db_lld_operations = CDBHelper::getAll('SELECT * from lld_override_operation WHERE '.
dbConditionId('lld_overrideid', (array) $db_lld_override['lld_overrideid'])
);
CTestArrayHelper::usort($db_lld_operations, ['lld_override_operationid']);
$this->assertLLDOverrideOperation($db_lld_operations[$num], $operation);
}
}
else {
$this->assertEquals(0, $db_lld_operations_count, 'Expected no operations.');
}
}
/**
* @param array $db_lld_override Table "lld_override" row (all fields).
* @param array $filter LLD rule override filter request object.
* @param array $filter['evaltype']
* @param array $filter['eval_formula'] (optional)
* @param array $filter['formula'] (optional) if evaltype is CONDITION_EVAL_TYPE_EXPRESSION
* @param array $filter['conditions']
* @param array $filter['conditions'][] LLD rule override filter condition object.
* @param array $filter['conditions'][]['macro']
* @param array $filter['conditions'][]['value']
* @param array $filter['conditions'][]['formulaid'] (optional) if evaltype is CONDITION_EVAL_TYPE_EXPRESSION
* @param array $filter['conditions'][]['operator'] (optional)
*/
private function assertLLDOverrideFilter(array $db_lld_override, array $filter) {
$db_lld_conditions = CDBHelper::getAll('SELECT * from lld_override_condition WHERE '.
dbConditionId('lld_overrideid', (array) $db_lld_override['lld_overrideid'])
);
CTestArrayHelper::usort($db_lld_conditions, ['lld_override_conditionid']);
$this->assertEquals($db_lld_override['evaltype'], $filter['evaltype'], 'Override evaltype value.');
if ($filter['evaltype'] == CONDITION_EVAL_TYPE_EXPRESSION) {
$conditionid_by_formulaid = array_combine(
array_column($filter['conditions'], 'formulaid'),
array_column($db_lld_conditions, 'lld_override_conditionid')
);
$formula = CConditionHelper::replaceLetterIds($filter['formula'], $conditionid_by_formulaid);
$this->assertEquals($db_lld_override['formula'], $formula);
}
foreach ($filter['conditions'] as $num => $condition) {
$this->assertEquals($db_lld_conditions[$num]['macro'], $condition['macro']);
$this->assertEquals($db_lld_conditions[$num]['value'], $condition['value']);
$operator = array_key_exists('operator', $condition)
? $condition['operator']
: CONDITION_OPERATOR_REGEXP;
$this->assertEquals($db_lld_conditions[$num]['operator'], $operator);
}
}
/**
* @param array $db_lld_override_op Table "lld_override_operation" row (all fields).
* @param string $db_lld_override_op['lld_override_operationid']
* @param string $db_lld_override_op['lld_overrideid']
* @param string $db_lld_override_op['operationobject']
* @param string $db_lld_override_op['operator']
* @param array $operation LLD rule override operation object.
* @param string $operation['operationobject']
* @param string $operation['operator'] (optional)
* @param string $operation['value'] (optional)
* @param string $operation['opstatus'] (optional)
* @param string $operation['opdiscover'] (optional)
* @param string $operation['opperiod'] (optional)
* @param string $operation['ophistory'] (optional)
* @param string $operation['optrends'] (optional)
* @param string $operation['opseverity'] (optional)
* @param string $operation['optag'] (optional)
* @param string $operation['optemplate'] (optional)
* @param string $operation['opinventory'] (optional)
*/
private function assertLLDOverrideOperation(array $db_lld_override_op, array $operation) {
$this->assertEquals($db_lld_override_op['operationobject'], $operation['operationobject'], 'Operation object.');
$condition_operator = array_key_exists('operator', $operation)
? $operation['operator']
: CONDITION_OPERATOR_EQUAL;
$this->assertEquals($db_lld_override_op['operator'], $condition_operator, 'Operation operator.');
$condition_value = array_key_exists('value', $operation)
? $operation['value']
: '';
$this->assertEquals($db_lld_override_op['value'], $condition_value);
$this->assertLLDOverrideOperationStatus($db_lld_override_op, $operation);
$this->assertLLDOverrideOperationDiscover($db_lld_override_op, $operation);
$this->assertLLDOverrideOperationHistory($db_lld_override_op, $operation);
$this->assertLLDOverrideOperationPeriod($db_lld_override_op, $operation);
$this->assertLLDOverrideOperationSeverity($db_lld_override_op, $operation);
$this->assertLLDOverrideOperationTags($db_lld_override_op, $operation);
$this->assertLLDOverrideOperationTemplates($db_lld_override_op, $operation);
$this->assertLLDOverrideOperationTrends($db_lld_override_op, $operation);
$this->assertLLDOverrideOperationInventory($db_lld_override_op, $operation);
}
/**
* @param array $db_lld_override_op
* @param array $operation
*/
private function assertLLDOverrideOperationStatus(array $db_lld_override_op, array $operation) {
$operationid = $db_lld_override_op['lld_override_operationid'];
$db_opstatus = CDBHelper::getRow('SELECT * from lld_override_opstatus WHERE '.
dbConditionId('lld_override_operationid', (array) $operationid)
);
if (array_key_exists('opstatus', $operation)) {
$this->assertEquals($db_opstatus['status'], $operation['opstatus']['status'], 'Operation status.');
}
else {
$this->assertEmpty($db_opstatus, 'Expected opstatus.');
}
}
/**
* @param array $db_lld_override_op
* @param array $operation
*/
private function assertLLDOverrideOperationDiscover(array $db_lld_override_op, array $operation) {
$operationid = $db_lld_override_op['lld_override_operationid'];
$db_opdiscover = CDBHelper::getRow('SELECT * from lld_override_opdiscover WHERE '.
dbConditionId('lld_override_operationid', (array) $operationid)
);
if (array_key_exists('opdiscover', $operation)) {
$this->assertEquals($db_opdiscover['discover'], $operation['opdiscover']['discover']);
}
else {
$this->assertEmpty($db_opdiscover, 'Discovery operation.');
}
}
/**
* @param array $db_lld_override_op
* @param array $operation
*/
private function assertLLDOverrideOperationHistory(array $db_lld_override_op, array $operation) {
$operationid = $db_lld_override_op['lld_override_operationid'];
$db_ophistory = CDBHelper::getRow('SELECT * from lld_override_ophistory WHERE '.
dbConditionId('lld_override_operationid', (array) $operationid)
);
if (array_key_exists('ophistory', $operation)) {
$this->assertEquals($db_ophistory['history'], $operation['ophistory']['history']);
}
else {
$this->assertEmpty($db_ophistory, 'ophistory.');
}
}
/**
* @param array $db_lld_override_op
* @param array $operation
*/
private function assertLLDOverrideOperationPeriod(array $db_lld_override_op, array $operation) {
$operationid = $db_lld_override_op['lld_override_operationid'];
$db_opperiod = CDBHelper::getRow('SELECT * from lld_override_opperiod WHERE '.
dbConditionId('lld_override_operationid', (array) $operationid)
);
if (array_key_exists('opperiod', $operation)) {
$this->assertEquals($db_opperiod['delay'], $operation['opperiod']['delay']);
}
else {
$this->assertEmpty($db_opperiod);
}
}
/**
* @param array $db_lld_override_op
* @param array $operation
*/
private function assertLLDOverrideOperationSeverity(array $db_lld_override_op, array $operation) {
$operationid = $db_lld_override_op['lld_override_operationid'];
$db_opseverity = CDBHelper::getRow('SELECT * from lld_override_opseverity WHERE '.
dbConditionId('lld_override_operationid', (array) $operationid)
);
if (array_key_exists('opseverity', $operation)) {
$this->assertEquals($db_opseverity['severity'], $operation['opseverity']['severity']);
}
else {
$this->assertEmpty($db_opseverity);
}
}
/**
* @param array $db_lld_override_op
* @param array $operation
*/
private function assertLLDOverrideOperationTags(array $db_lld_override_op, array $operation) {
$db_optags = CDBHelper::getAll(
'SELECT tag,value'.
' FROM lld_override_optag'.
' WHERE '.dbConditionId('lld_override_operationid', [$db_lld_override_op['lld_override_operationid']])
);
CTestArrayHelper::usort($db_optags, ['tag', 'value']);
$operation['optag'] = array_key_exists('optag', $operation)
? array_map(function($a) {
if (!array_key_exists('value', $a)) {
$a['value'] = '';
}
return $a;
}, $operation['optag'])
: [];
CTestArrayHelper::usort($operation['optag'], ['tag', 'value']);
$this->assertSame($db_optags, $operation['optag']);
}
/**
* @param array $db_lld_override_op
* @param array $operation
*/
private function assertLLDOverrideOperationTemplates(array $db_lld_override_op, array $operation) {
$db_optemplates = CDBHelper::getAll(
'SELECT templateid'.
' FROM lld_override_optemplate'.
' WHERE '.dbConditionId('lld_override_operationid', [$db_lld_override_op['lld_override_operationid']])
);
CTestArrayHelper::usort($db_optemplates, ['templateid']);
if (!array_key_exists('optemplate', $operation)) {
$operation['optemplate'] = [];
}
CTestArrayHelper::usort($operation['optemplate'], ['templateid']);
$this->assertSame($db_optemplates, $operation['optemplate']);
}
/**
* @param array $db_lld_override_op
* @param array $operation
*/
private function assertLLDOverrideOperationTrends(array $db_lld_override_op, array $operation) {
$operationid = $db_lld_override_op['lld_override_operationid'];
$db_optrends = CDBHelper::getRow('SELECT * from lld_override_optrends WHERE '.
dbConditionId('lld_override_operationid', (array) $operationid)
);
if (array_key_exists('optrends', $operation)) {
$this->assertEquals($db_optrends['trends'], $operation['optrends']['trends']);
}
else {
$this->assertEmpty($db_optrends, 'optrends');
}
}
/**
* @param array $db_lld_override_op
* @param array $operation
*/
private function assertLLDOverrideOperationInventory(array $db_lld_override_op, array $operation) {
$operationid = $db_lld_override_op['lld_override_operationid'];
$db_opinventory = CDBHelper::getRow('SELECT * from lld_override_opinventory WHERE '.
dbConditionId('lld_override_operationid', (array) $operationid)
);
if (array_key_exists('opinventory', $operation)) {
$this->assertEquals($db_opinventory['inventory_mode'], $operation['opinventory']['inventory_mode']);
}
else {
$this->assertEmpty($db_opinventory);
}
}
public function testDiscoveryRuleOverrides_TemplateConstraint() {
$templateid = '131001';
$itemid = '133766';
$request_lld_overrides = [
[
'stop' => ZBX_LLD_OVERRIDE_STOP_NO,
'name' => 'Only template operation',
'step' => 1,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'optemplate' => [
['templateid' => $templateid]
]
]
]
],
[
'stop' => ZBX_LLD_OVERRIDE_STOP_NO,
'name' => 'Not only template operation',
'step' => 2,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'opinventory' => [
'inventory_mode' => HOST_INVENTORY_MANUAL
],
'optemplate' => [
['templateid' => $templateid]
]
]
]
]
];
$db_lld_overrides = CDBHelper::getAll('SELECT * from lld_override WHERE '.
dbConditionId('itemid', (array) $itemid)
);
CTestArrayHelper::usort($db_lld_overrides, ['lld_overrideid']);
// Assertion confirms existing request.
foreach ($request_lld_overrides as $override_num => $request_lld_override) {
$this->assertLLDOverride($db_lld_overrides[$override_num], $request_lld_override);
}
$result = $this->call('template.delete', [131001]);
$this->assertEquals($result['result'], ['templateids' => [$templateid]]);
$db_lld_overrides = CDBHelper::getAll('SELECT * from lld_override WHERE '.
dbConditionId('itemid', (array) $itemid)
);
CTestArrayHelper::usort($db_lld_overrides, ['lld_overrideid']);
// Operation that had only optemplate is deleted.
unset($request_lld_overrides[0]['operations']);
// Operation that had not only optemplate is not deleted.
unset($request_lld_overrides[1]['operations'][0]['optemplate']);
foreach ($request_lld_overrides as $override_num => $request_lld_override) {
$this->assertLLDOverride($db_lld_overrides[$override_num], $request_lld_override);
}
}
public function testDiscoveryRuleOverrides_Copy() {
$itemid = '133764';
$hostids = ['90020', '90021'];
$result = $this->call('discoveryrule.copy', [
'discoveryids' => [$itemid],
'hostids' => $hostids
]);
$this->assertTrue($result['result']);
$result = $this->call('discoveryrule.get', [
'output' => [],
'selectOverrides' => 'extend',
'itemids' => $itemid
]);
$expected_overrides = $result['result'][0]['overrides'];
CTestArrayHelper::usort($expected_overrides, ['step']);
foreach ($expected_overrides as &$override) {
CTestArrayHelper::usort($override['filter']['conditions'], ['formulaid']);
CTestArrayHelper::usort($override['operations'], ['operationobject', 'operator', 'value']);
foreach ($override['operations'] as &$operation) {
if (array_key_exists('optag', $operation)) {
CTestArrayHelper::usort($operation['optag'], ['tag']);
}
if (array_key_exists('optemplate', $operation)) {
CTestArrayHelper::usort($operation['optemplate'], ['templateid']);
}
}
unset($operation);
}
unset($override);
$db_lld_ruleids = array_column(CDBHelper::getAll(
'SELECT itemid FROM items WHERE flags=1 AND '.dbConditionId('hostid', $hostids).' ORDER BY itemid'
), 'itemid');
$this->assertSame(count($db_lld_ruleids), count($hostids));
$result = $this->call('discoveryrule.get', [
'output' => [],
'selectOverrides' => 'extend',
'itemids' => $db_lld_ruleids
]);
foreach ($result['result'] as $lld_rule) {
CTestArrayHelper::usort($lld_rule['overrides'], ['step']);
foreach ($lld_rule['overrides'] as &$override) {
CTestArrayHelper::usort($override['filter']['conditions'], ['formulaid']);
CTestArrayHelper::usort($override['operations'], ['operationobject', 'operator', 'value']);
foreach ($override['operations'] as &$operation) {
if (array_key_exists('optag', $operation)) {
CTestArrayHelper::usort($operation['optag'], ['tag']);
}
if (array_key_exists('optemplate', $operation)) {
CTestArrayHelper::usort($operation['optemplate'], ['templateid']);
}
}
unset($operation);
}
unset($override);
$this->assertSame($expected_overrides, $lld_rule['overrides']);
}
}
public static function discoveryrule_overrides_get_data_valid() {
$itemid = '133763';
return [
'Test getting lld_overrides extended output.' => [
'discoveryrule' => [
'output' => ['itemid'],
'selectOverrides' => ['name', 'step', 'stop', 'operations'],
'itemids' => [$itemid]
],
'get_result' => [
'itemid' => $itemid,
'overrides' => [
[
'name' => 'override',
'step' => '1',
'stop' => ZBX_LLD_OVERRIDE_STOP_YES,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_EXPRESSION,
'formula' => 'A or B or C',
'conditions' => [
[
'macro' => '{#MACRO1}',
'value' => 'd{3}$',
'operator' => CONDITION_OPERATOR_REGEXP,
'formulaid' => 'A'
],
[
'macro' => '{#MACRO2}',
'value' => 'd{2}$',
'operator' => CONDITION_OPERATOR_REGEXP,
'formulaid' => 'B'
],
[
'macro' => '{#MACRO3}',
'value' => 'd{1}$',
'operator' => CONDITION_OPERATOR_REGEXP,
'formulaid' => 'C'
]
],
'eval_formula' => 'A or B or C'
],
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_LIKE,
'value' => '8',
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_DISABLED
]
],
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_EQUAL,
'value' => 'wW',
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_ENABLED
],
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_NO_DISCOVER
],
'ophistory' => [
'history' => '92d'
],
'optrends' => [
'trends' => '36d'
],
'opperiod' => [
'delay' => '1m;wd1-3h4-16;10s/1-5,00:00-20:00;5s/5-7,00:00-24:00'
]
],
[
'operationobject' => OPERATION_OBJECT_TRIGGER_PROTOTYPE,
'operator' => CONDITION_OPERATOR_REGEXP,
'value' => '^c+$',
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_DISABLED
],
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_NO_DISCOVER
],
'opseverity' => [
'severity' => TRIGGER_SEVERITY_AVERAGE
],
'optag' => [
[
'tag' => 'tag1',
'value' => 'value1'
],
[
'tag' => 'tag2',
'value' => 'value2'
]
]
],
[
'operationobject' => OPERATION_OBJECT_GRAPH_PROTOTYPE,
'operator' => CONDITION_OPERATOR_LIKE,
'value' => '123',
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_NO_DISCOVER
]
],
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'operator' => CONDITION_OPERATOR_EQUAL,
'value' => '',
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_DISABLED
],
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_NO_DISCOVER
],
'optemplate' => [
[
'templateid' => '10264'
],
[
'templateid' => '10265'
],
[
'templateid' => '50010'
]
],
'optag' => [
[
'tag' => 'tag1',
'value' => 'value1'
],
[
'tag' => 'tag2',
'value' => 'value2'
]
],
'opinventory' => [
'inventory_mode' => HOST_INVENTORY_AUTOMATIC
]
]
]
],
[
'name' => 'override 2',
'step' => '2',
'stop' => ZBX_LLD_OVERRIDE_STOP_YES,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_AND_OR,
'formula' => '',
'conditions' => [],
'eval_formula' => ''
],
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_EQUAL,
'value' => '',
'optrends' => [
'trends' => '5d'
]
]
]
]
]
],
'expected_error' => null
],
'Test getting lld_overrides queried output.' => [
'discoveryrule' => [
'output' => ['itemid'],
'selectOverrides' => ['step', 'operations'],
'itemids' => [$itemid]
],
'get_result' => [
'itemid' => $itemid,
'overrides' => [
[
'step' => '1',
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_LIKE,
'value' => '8',
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_DISABLED
]
],
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_EQUAL,
'value' => 'wW',
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_ENABLED
],
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_NO_DISCOVER
],
'ophistory' => [
'history' => '92d'
],
'optrends' => [
'trends' => '36d'
],
'opperiod' => [
'delay' => '1m;wd1-3h4-16;10s/1-5,00:00-20:00;5s/5-7,00:00-24:00'
]
],
[
'operationobject' => OPERATION_OBJECT_TRIGGER_PROTOTYPE,
'operator' => CONDITION_OPERATOR_REGEXP,
'value' => '^c+$',
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_DISABLED
],
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_NO_DISCOVER
],
'opseverity' => [
'severity' => TRIGGER_SEVERITY_AVERAGE
],
'optag' => [
[
'tag' => 'tag1',
'value' => 'value1'
],
[
'tag' => 'tag2',
'value' => 'value2'
]
]
],
[
'operationobject' => OPERATION_OBJECT_GRAPH_PROTOTYPE,
'operator' => CONDITION_OPERATOR_LIKE,
'value' => '123',
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_NO_DISCOVER
]
],
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'operator' => CONDITION_OPERATOR_EQUAL,
'value' => '',
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_DISABLED
],
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_NO_DISCOVER
],
'optemplate' => [
[
'templateid' => '10264'
],
[
'templateid' => '10265'
],
[
'templateid' => '50010'
]
],
'optag' => [
[
'tag' => 'tag1',
'value' => 'value1'
],
[
'tag' => 'tag2',
'value' => 'value2'
]
],
'opinventory' => [
'inventory_mode' => HOST_INVENTORY_AUTOMATIC
]
]
]
],
[
'step' => '2',
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_EQUAL,
'value' => '',
'optrends' => [
'trends' => '5d'
]
]
]
]
]
],
'expected_error' => null
]
];
}
/**
* @dataProvider discoveryrule_overrides_get_data_valid
*/
public function testDiscoveryRuleOverrides_Get($discoveryrule, $get_result, $expected_error) {
$result = $this->call('discoveryrule.get', $discoveryrule);
if ($expected_error === null) {
foreach ($result['result'] as $entry) {
$this->assertSame($entry['itemid'], $get_result['itemid']);
if (array_key_exists('selectOverrides', $discoveryrule)) {
$this->assertArrayHasKey('overrides', $get_result);
$this->assertSame($entry['overrides'], $get_result['overrides']);
}
else {
$this->assertArrayNotHasKey('overrides', $get_result);
}
}
}
}
public static function discoveryrule_overrides_update_data() {
$itemid = '133765';
$initial_overrides = [
[
'name' => 'override',
'step' => '1',
'stop' => ZBX_LLD_OVERRIDE_STOP_YES,
'filter' => [
'evaltype' => CONDITION_EVAL_TYPE_EXPRESSION,
'formula' => 'A or B or C',
'conditions' => [
[
'macro' => '{#MACRO1}',
'value' => 'd{3}$',
'operator' => CONDITION_OPERATOR_REGEXP,
'formulaid' => 'A'
],
[
'macro' => '{#MACRO2}',
'value' => 'd{2}$',
'operator' => CONDITION_OPERATOR_REGEXP,
'formulaid' => 'B'
],
[
'macro' => '{#MACRO3}',
'value' => 'd{1}$',
'operator' => CONDITION_OPERATOR_REGEXP,
'formulaid' => 'C'
]
]
],
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_LIKE,
'value' => '8',
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_DISABLED
]
],
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_NOT_EQUAL,
'value' => 'wW',
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_ENABLED
],
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_NO_DISCOVER
],
'ophistory' => [
'history' => '92d'
],
'optrends' => [
'trends' => '36d'
],
'opperiod' => [
'delay' => '1m;wd1-3h4-16;10s/1-5,00:00-20:00;5s/5-7,00:00-24:00'
]
],
[
'operationobject' => OPERATION_OBJECT_TRIGGER_PROTOTYPE,
'operator' => CONDITION_OPERATOR_REGEXP,
'value' => '^c+$',
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_DISABLED
],
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_NO_DISCOVER
],
'opseverity' => [
'severity' => TRIGGER_SEVERITY_AVERAGE
],
'optag' => [
[
'tag' => 'tag1',
'value' => 'value1'
],
[
'tag' => 'tag2',
'value' => 'value2'
]
]
],
[
'operationobject' => OPERATION_OBJECT_GRAPH_PROTOTYPE,
'operator' => CONDITION_OPERATOR_LIKE,
'value' => '123',
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_NO_DISCOVER
]
],
[
'operationobject' => OPERATION_OBJECT_HOST_PROTOTYPE,
'operator' => CONDITION_OPERATOR_EQUAL,
'value' => '',
'opstatus' => [
'status' => ZBX_PROTOTYPE_STATUS_DISABLED
],
'opdiscover' => [
'discover' => ZBX_PROTOTYPE_NO_DISCOVER
],
'optemplate' => [
[
'templateid' => '10264'
],
[
'templateid' => '10265'
],
[
'templateid' => '50010'
]
],
'optag' => [
[
'tag' => 'tag1',
'value' => 'value1'
],
[
'tag' => 'tag2',
'value' => 'value2'
]
],
'opinventory' => [
'inventory_mode' => HOST_INVENTORY_AUTOMATIC
]
]
]
],
[
'name' => 'override 2',
'step' => '2',
'stop' => ZBX_LLD_OVERRIDE_STOP_YES,
'operations' => [
[
'operationobject' => OPERATION_OBJECT_ITEM_PROTOTYPE,
'operator' => CONDITION_OPERATOR_EQUAL,
'value' => '',
'optrends' => [
'trends' => '5d'
]
]
]
]
];
$edited_overrides = $initial_overrides;
unset($edited_overrides[1]);
$edited_overrides[0]['name'] = 'edited override';
$edited_invalid_overrides = $initial_overrides;
$edited_invalid_overrides[1]['operations'][0]['optrends']['trends'] = 'incorrect date value';
return [
'Test update override expects array.' => [
'request' => [
'itemid' => $itemid,
'overrides' => [
'incorrect' => '123'
]
],
'expected_error' => 'Invalid parameter "/1/overrides/1": unexpected parameter "incorrect".',
'current_overrides' => null
],
'Test override object is validated.' => [
'request' => [
'itemid' => $itemid,
'overrides' => [
[]
]
],
'expected_error' => 'Invalid parameter "/1/overrides/1": the parameter "name" is missing.',
'current_overrides' => null
],
'Test that overrides remain untouched if update request omits overrides field.' => [
'request' => [
'itemid' => $itemid
],
'expected_error' => null,
'current_overrides' => $initial_overrides
],
'Test all overrides array can only be completely rewritten.' => [
'request' => [
'itemid' => $itemid,
'overrides' => $edited_overrides
],
'expected_error' => null,
'current_overrides' => $edited_overrides
],
'Test overrides/2/operations/1/optrends/trends is validated.' => [
'request' => [
'itemid' => $itemid,
'overrides' => $edited_invalid_overrides
],
'expected_error' => 'Invalid parameter "/1/overrides/2/operations/1/optrends/trends": a time unit is expected.',
'current_overrides' => null
],
'Test all overrides can deleted.' => [
'request' => [
'itemid' => $itemid,
'overrides' => []
],
'expected_error' => null,
'current_overrides' => []
],
'Test all overrides can be recreated.' => [
'request' => [
'itemid' => $itemid,
'overrides' => $initial_overrides
],
'expected_error' => null,
'current_overrides' => $initial_overrides
]
];
}
/**
* @dataProvider discoveryrule_overrides_update_data
*/
public function testDiscoveryRuleOverrides_Update($request, $expected_error, $current_overrides) {
$this->call('discoveryrule.update', $request, $expected_error);
if ($expected_error === null) {
$itemid = $request['itemid'];
$db_lld_overrides = CDBHelper::getAll('SELECT * from lld_override WHERE '.
dbConditionId('itemid', (array) $itemid)
);
CTestArrayHelper::usort($db_lld_overrides, ['lld_overrideid']);
if (array_key_exists('overrides', $request)) {
$this->assertEquals(count($current_overrides), count($request['overrides']));
}
foreach ($current_overrides as $override_num => $override) {
$this->assertLLDOverride($db_lld_overrides[$override_num], $override);
}
}
}
// TODO: add more tests to check other related discovery rule properties and perform more tests on templates and templated objects.
}