|
|
|
|
<?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/CWebTest.php';
|
|
|
|
|
require_once dirname(__FILE__).'/../../include/helpers/CDataHelper.php';
|
|
|
|
|
require_once dirname(__FILE__).'/../behaviors/CMessageBehavior.php';
|
|
|
|
|
require_once dirname(__FILE__).'/../traits/PreprocessingTrait.php';
|
|
|
|
|
use Facebook\WebDriver\Exception\ElementClickInterceptedException;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test the mass update of items and item prototypes.
|
|
|
|
|
*
|
|
|
|
|
* @backup items, interface
|
|
|
|
|
*/
|
|
|
|
|
class testMassUpdateItems extends CWebTest{
|
|
|
|
|
|
|
|
|
|
use PreprocessingTrait;
|
|
|
|
|
|
|
|
|
|
const HOSTID = 40001; // Simple form test host.
|
|
|
|
|
const RULEID = 133800; // testFormDiscoveryRule1 on Simple form test host.
|
|
|
|
|
const HOST_NAME = 'Simple form test host';
|
|
|
|
|
const AGENT_INTERFACE_ID = 40011;
|
|
|
|
|
const SNMP2_INTERFACE_ID = 40012;
|
|
|
|
|
const IPMI_INTERFACE_ID = 40013;
|
|
|
|
|
|
|
|
|
|
const INTERVAL_MAPPING = [
|
|
|
|
|
'Type' => [
|
|
|
|
|
'name' => 'type',
|
|
|
|
|
'class' => 'CSegmentedRadioElement',
|
|
|
|
|
'selector' => 'xpath:./ul[contains(@class, "radio-list-control")]'.
|
|
|
|
|
'|./ul/li/ul[contains(@class, "radio-list-control")]|./div/ul[contains(@class, "radio-list-control")]'
|
|
|
|
|
],
|
|
|
|
|
'Interval' => [
|
|
|
|
|
'name' => 'delay',
|
|
|
|
|
'class' => 'CElement',
|
|
|
|
|
'selector' => 'xpath:./input[@name][not(@type) or @type="text" or @type="password"][not(@style) or '.
|
|
|
|
|
'not(contains(@style,"display: none"))]|./textarea[@name]'
|
|
|
|
|
],
|
|
|
|
|
'Period' => [
|
|
|
|
|
'name' => 'period',
|
|
|
|
|
'class' => 'CElement',
|
|
|
|
|
'selector' => 'xpath:./input[@name][not(@type) or @type="text" or @type="password"][not(@style) or '.
|
|
|
|
|
'not(contains(@style,"display: none"))]|./textarea[@name]'
|
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Attach MessageBehavior to the test.
|
|
|
|
|
*
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
|
|
|
|
public function getBehaviors() {
|
|
|
|
|
return ['class' => CMessageBehavior::class];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Add interface to host.
|
|
|
|
|
*/
|
|
|
|
|
public function prepareInterfaceData() {
|
|
|
|
|
CDataHelper::call('hostinterface.create', [
|
|
|
|
|
[
|
|
|
|
|
'hostid' => self::HOSTID,
|
|
|
|
|
'dns' => '',
|
|
|
|
|
'ip' => '127.0.5.5',
|
|
|
|
|
'main' => 0,
|
|
|
|
|
'port' => '10055',
|
|
|
|
|
'type' => 2,
|
|
|
|
|
'useip' => 1,
|
|
|
|
|
'details' => [
|
|
|
|
|
'version' => 3,
|
|
|
|
|
'bulk' => 1,
|
|
|
|
|
'max_repetitions' => 10,
|
|
|
|
|
'securityname' => 'zabbix',
|
|
|
|
|
'securitylevel' => 0,
|
|
|
|
|
'authprotocol' => 0,
|
|
|
|
|
'privprotocol' => 0,
|
|
|
|
|
'contextname' => 'zabbix'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Data for mass updating of items and item prototypes.
|
|
|
|
|
*/
|
|
|
|
|
public function getCommonChangeData() {
|
|
|
|
|
return [
|
|
|
|
|
// #0.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'7_IPMI',
|
|
|
|
|
'8_IPMI'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'SNMP agent']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/snmp_oid": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #1.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'13_DB_Monitor',
|
|
|
|
|
'14_DB_Monitor'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'TELNET agent']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/2/username": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #2.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'TELNET agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/username": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #3.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'SSH agent'],
|
|
|
|
|
'Authentication method' => ['id' => 'authtype', 'value' => 'Password'],
|
|
|
|
|
'User name' => ['id' => 'username', 'value' => '']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/username": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #4.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'SSH agent'],
|
|
|
|
|
'Authentication method' => ['id' => 'authtype', 'value' => 'Public key'],
|
|
|
|
|
'User name' => ['id' => 'username', 'value' => ''],
|
|
|
|
|
'Public key file' => ['id' => 'publickey', 'value' => '/path/file1'],
|
|
|
|
|
'Private key file' => ['id' => 'privatekey', 'value' => '/path/file2']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/username": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #5.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'SSH agent'],
|
|
|
|
|
'Authentication method' => ['id' => 'authtype', 'value' => 'Public key'],
|
|
|
|
|
'User name' => ['id' => 'username', 'value' => 'new_test_name'],
|
|
|
|
|
'Public key file' => ['id' => 'publickey', 'value' => ''],
|
|
|
|
|
'Private key file' => ['id' => 'privatekey', 'value' => '/path/file2']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/publickey": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #6.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'SSH agent'],
|
|
|
|
|
'Authentication method' => ['id' => 'authtype', 'value' => 'Public key'],
|
|
|
|
|
'User name' => ['id' => 'username', 'value' => 'new_test_name'],
|
|
|
|
|
'Public key file' => ['id' => 'publickey', 'value' => '/path/file1'],
|
|
|
|
|
'Private key file' => ['id' => 'privatekey', 'value' => '']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/privatekey": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #7.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'History storage period' => [
|
|
|
|
|
'radio' => ['id' => 'history_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'history', 'value' => '3599']
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/history": value must be one of 0, 3600-788400000.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #8.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'History storage period' => [
|
|
|
|
|
'radio' => ['id' => 'history_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'history', 'value' => '1']
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/history": value must be one of 0, 3600-788400000.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #9.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'History storage period' => [
|
|
|
|
|
'radio' => ['id' => 'history_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'history', 'value' => '']
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/history": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #10.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'History storage period' => [
|
|
|
|
|
'radio' => ['id' => 'history_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'history', 'value' => '25y']
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/history": a time unit is expected.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #11.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'Trend storage period' => [
|
|
|
|
|
'radio' => ['id' => 'trends_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'trends', 'value' => '']
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/trends": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #12.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'Trend storage period' => [
|
|
|
|
|
'radio' => ['id' => 'trends_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'trends', 'value' => '86399']
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/trends": value must be one of 0, 86400-788400000.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #13.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'Trend storage period' => [
|
|
|
|
|
'radio' => ['id' => 'trends_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'trends', 'value' => '1']
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/trends": value must be one of 0, 86400-788400000.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #14.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'Trend storage period' => [
|
|
|
|
|
'radio' => ['id' => 'trends_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'trends', 'value' => '25y']
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/trends": a time unit is expected.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #15.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix trapper'],
|
|
|
|
|
'Allowed hosts' => ['id' => 'trapper_hosts', 'value' => 'Zabbix server']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/trapper_hosts": invalid address range "Zabbix server".'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #16.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Update interval' => ['Delay' => '']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/delay": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #17.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Update interval' => ['Delay' => '0']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/delay": cannot be equal to zero without custom intervals.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #18.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Update interval' => ['Delay' => '86401']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/delay": value must be one of 0-86400.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #19.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Update interval' => [
|
|
|
|
|
'Delay' => '1d',
|
|
|
|
|
'Custom intervals' => [
|
|
|
|
|
[
|
|
|
|
|
'type' => 'Flexible',
|
|
|
|
|
'delay' => '99s',
|
|
|
|
|
'period' => ''
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid interval "".'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #20.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Update interval' => [
|
|
|
|
|
'Delay' => '1s',
|
|
|
|
|
'Custom intervals' => [
|
|
|
|
|
[
|
|
|
|
|
'type' => 'Flexible',
|
|
|
|
|
'delay' => '',
|
|
|
|
|
'period' => '1-5,00:00-1:00'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid interval "".'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #21.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Update interval' => [
|
|
|
|
|
'Delay' => '24h',
|
|
|
|
|
'Custom intervals' => [
|
|
|
|
|
[
|
|
|
|
|
'type' => 'Scheduling',
|
|
|
|
|
'delay' => 'test'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid interval "test".'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #22.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'HTTP agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'URL' => ['id' => 'url', 'value' => 'https//:zabbix.com'],
|
|
|
|
|
'Headers' => [
|
|
|
|
|
[
|
|
|
|
|
'action' => USER_ACTION_UPDATE,
|
|
|
|
|
'index' => 0,
|
|
|
|
|
'name' => '',
|
|
|
|
|
'value' => 'header value 1'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/headers": nonempty key and value pair expected.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #23.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'HTTP agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'URL' => ['id' => 'url', 'value' => 'https//:zabbix.com'],
|
|
|
|
|
'Headers' => [
|
|
|
|
|
[
|
|
|
|
|
'action' => USER_ACTION_UPDATE,
|
|
|
|
|
'index' => 0,
|
|
|
|
|
'name' => 'header name 1',
|
|
|
|
|
'value' => ''
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/headers": nonempty key and value pair expected.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #24.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'HTTP agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'URL' => ['id' => 'url', 'value' => 'https//:zabbix.com'],
|
|
|
|
|
'Request body type' => ['id' => 'post_type_container', 'value' => 'JSON data'],
|
|
|
|
|
'Request body' => ['id' => 'posts', 'value' => '"request": "active checks", "host": "host"']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/posts": JSON is expected.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #25.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'HTTP agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'URL' => ['id' => 'url', 'value' => 'https//:zabbix.com'],
|
|
|
|
|
'Request body type' => ['id' => 'post_type_container', 'value' => 'XML data'],
|
|
|
|
|
'Request body' => ['id' => 'posts', 'value' => 'xml version="1.0" encoding="UTF-8"?<zabbix_export></zabbix_export>']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/posts": (4) Start tag expected, \'<\' not found [Line: 1 | Column: 1].'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #26.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'HTTP agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'URL' => ['id' => 'url', 'value' => 'https//:zabbix.com'],
|
|
|
|
|
'Request body type' => ['id' => 'post_type_container', 'value' => 'XML data'],
|
|
|
|
|
'Request body' => ['id' => 'posts', 'value' => '']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/posts": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #27.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'HTTP agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'URL' => ['id' => 'url', 'value' => '']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/url": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #28.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'JMX agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.4:10054'],
|
|
|
|
|
'JMX endpoint' => ['id' => 'jmx_endpoint', 'value' => '']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/jmx_endpoint": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #29.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'JMX agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.4:10054'],
|
|
|
|
|
'JMX endpoint' => [
|
|
|
|
|
'id' => 'jmx_endpoint',
|
|
|
|
|
'value' => 'service:jmx:rmi:///jndi/rmi://{HOST.CONN}:{HOST.PORT}/jmxrmi'
|
|
|
|
|
],
|
|
|
|
|
'User name' => ['id' => 'username', 'value' => 'new_test_name'],
|
|
|
|
|
'Password' => ['id' => 'password', 'value' => '']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1": both username and password should be either present or empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #30.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'JMX agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.4:10054'],
|
|
|
|
|
'JMX endpoint' => [
|
|
|
|
|
'id' => 'jmx_endpoint',
|
|
|
|
|
'value' => 'service:jmx:rmi:///jndi/rmi://{HOST.CONN}:{HOST.PORT}/jmxrmi'
|
|
|
|
|
],
|
|
|
|
|
'User name' => ['id' => 'username', 'value' => ''],
|
|
|
|
|
'Password' => ['id' => 'password', 'value' => 'new_test_password']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1": both username and password should be either present or empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #31.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'SNMP agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.5:10055']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/snmp_oid": cannot be empty.',
|
|
|
|
|
'interface_text_part' => 'SNMPv3, Context name: zabbix'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #32.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'17_Script',
|
|
|
|
|
'18_Script'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Timeout' => ['id' => 'timeout', 'value' => '0']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/timeout": value must be one of 1-60.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #33.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'17_Script',
|
|
|
|
|
'18_Script'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Timeout' => ['id' => 'timeout', 'value' => '61']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/timeout": value must be one of 1-60.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #34.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'17_Script',
|
|
|
|
|
'18_Script'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Timeout' => ['id' => 'timeout', 'value' => '']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/timeout": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #35.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'17_Script',
|
|
|
|
|
'18_Script'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Timeout' => ['id' => 'timeout', 'value' => '60s']
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #36.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent (active)'],
|
|
|
|
|
'Type of information' => ['id' => 'value_type', 'value' => 'Numeric (float)'],
|
|
|
|
|
'Units' => ['id' => 'units', 'value' => '$'],
|
|
|
|
|
'Update interval' => [
|
|
|
|
|
'Delay' => '99s',
|
|
|
|
|
'Custom intervals' => [
|
|
|
|
|
[
|
|
|
|
|
'action' => USER_ACTION_UPDATE,
|
|
|
|
|
'index' => 0,
|
|
|
|
|
'type' => 'Flexible',
|
|
|
|
|
'delay' => '60s',
|
|
|
|
|
'period' => '2-5,3:00-17:00'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'type' => 'Scheduling',
|
|
|
|
|
'delay' => 'wd3-4h1-15'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'History storage period' => [
|
|
|
|
|
'radio' => ['id' => 'history_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'history', 'value' => '400d']
|
|
|
|
|
],
|
|
|
|
|
'Trend storage period' => [
|
|
|
|
|
'radio' => ['id' => 'trends_mode', 'value' => 'Do not keep trends']
|
|
|
|
|
],
|
|
|
|
|
'Value mapping' => ['id' => 'valuemapid', 'value' => 'Reference valuemap'],
|
|
|
|
|
'Description' => ['id' => 'description', 'value' => 'New mass updated description']
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #37.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'History storage period' => [
|
|
|
|
|
'radio' => ['id' => 'history_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'history', 'value' => '0']
|
|
|
|
|
],
|
|
|
|
|
'Trend storage period' => [
|
|
|
|
|
'radio' => ['id' => 'trends_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'trends', 'value' => '0']
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #38.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'History storage period' => [
|
|
|
|
|
'radio' => ['id' => 'history_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'history', 'value' => '3600']
|
|
|
|
|
],
|
|
|
|
|
'Trend storage period' => [
|
|
|
|
|
'radio' => ['id' => 'trends_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'trends', 'value' => '86400']
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #39.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'History storage period' => [
|
|
|
|
|
'radio' => ['id' => 'history_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'history', 'value' => '9125d']
|
|
|
|
|
],
|
|
|
|
|
'Trend storage period' => [
|
|
|
|
|
'radio' => ['id' => 'trends_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'trends', 'value' => '9125d']
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #40.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'History storage period' => [
|
|
|
|
|
'radio' => ['id' => 'history_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'history', 'value' => '219000h']
|
|
|
|
|
],
|
|
|
|
|
'Trend storage period' => [
|
|
|
|
|
'radio' => ['id' => 'trends_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'trends', 'value' => '219000h']
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #41.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'History storage period' => [
|
|
|
|
|
'radio' => ['id' => 'history_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'history', 'value' => '13140000m']
|
|
|
|
|
],
|
|
|
|
|
'Trend storage period' => [
|
|
|
|
|
'radio' => ['id' => 'trends_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'trends', 'value' => '13140000m']
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #42.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Simple check'],
|
|
|
|
|
'Type of information' => ['id' => 'value_type', 'value' => 'Log'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.2:10052'],
|
|
|
|
|
'User name' => ['id' => 'username', 'value' => 'test_username'],
|
|
|
|
|
'Password' => ['id' => 'password', 'value' => 'test_password'],
|
|
|
|
|
'Log time format' => ['id' => 'logtimefmt', 'value' => 'PPPPPP:YYYYMMDD:HHMMSS.mmm']
|
|
|
|
|
],
|
|
|
|
|
'interface_text_part' => 'SNMPv2, Community: {$SNMP_COMMUNITY}'
|
|
|
|
|
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #43.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix internal'],
|
|
|
|
|
'Type of information' => ['id' => 'value_type', 'value' => 'Text'],
|
|
|
|
|
'Update interval' => [
|
|
|
|
|
'Delay' => '1d',
|
|
|
|
|
'Custom intervals' => [
|
|
|
|
|
[
|
|
|
|
|
'action' => USER_ACTION_UPDATE,
|
|
|
|
|
'index' => 0,
|
|
|
|
|
'type' => 'Scheduling',
|
|
|
|
|
'delay' => 'wd3-4h1-15'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'type' => 'Flexible',
|
|
|
|
|
'delay' => '99s',
|
|
|
|
|
'period' => '1-2,7:00-8:00'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #44.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix trapper'],
|
|
|
|
|
'Type of information' => ['id' => 'value_type', 'value' => 'Numeric (unsigned)'],
|
|
|
|
|
'Allowed hosts' => ['id' => 'trapper_hosts', 'value' => '127.0.0.1']
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #45.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix trapper'],
|
|
|
|
|
'Allowed hosts' => ['id' => 'trapper_hosts', 'value' => '{HOST.HOST}']
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #46.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix trapper'],
|
|
|
|
|
'Allowed hosts' => [
|
|
|
|
|
'id' => 'trapper_hosts',
|
|
|
|
|
'value' => '192.168.1.0/24, 192.168.3.1-255, 192.168.1-10.1-255, ::1,2001:db8::/32, zabbix.domain'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #47.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'External check'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'Update interval' => ['Delay' => '1440m']
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #48.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'HTTP agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051'],
|
|
|
|
|
'URL' => ['id' => 'url', 'value' => 'https//:zabbix.com'],
|
|
|
|
|
'Request body type' => ['id' => 'post_type_container', 'value' => 'JSON data'],
|
|
|
|
|
'Request body' => ['id' => 'posts', 'value' => '{"request": "active checks", "host": "host"}'],
|
|
|
|
|
'Headers' => [
|
|
|
|
|
[
|
|
|
|
|
'action' => USER_ACTION_UPDATE,
|
|
|
|
|
'index' => 0,
|
|
|
|
|
'name' => 'header name 1',
|
|
|
|
|
'value' => 'header value 1'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'name' => 'header name 2',
|
|
|
|
|
'value' => 'header value 2'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'Type of information' => ['id' => 'value_type', 'value' => 'Numeric (float)'],
|
|
|
|
|
'Units' => ['id' => 'units', 'value' => 'kB'],
|
|
|
|
|
'Update interval' => ['Delay' => '86400'],
|
|
|
|
|
'Enable trapping' => ['id' => 'allow_traps', 'value' => 'Yes']
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'screenshot' => true
|
|
|
|
|
],
|
|
|
|
|
// #49.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'JMX agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.4:10054'],
|
|
|
|
|
'JMX endpoint' => [
|
|
|
|
|
'id' => 'jmx_endpoint',
|
|
|
|
|
'value' => 'service:jmx:rmi:///jndi/rmi://{HOST.CONN}:{HOST.PORT}/jmxrmi'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #50.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item',
|
|
|
|
|
'2_Item'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Zabbix agent'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.1:10051']
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #51.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'7_IPMI',
|
|
|
|
|
'8_IPMI'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'IPMI agent'],
|
|
|
|
|
'Type of information' => ['id' => 'value_type', 'value' => 'Numeric (float)'],
|
|
|
|
|
'Units' => ['id' => 'units', 'value' => 'kB'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.3:10053']
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #52.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'3_SNMP_trap',
|
|
|
|
|
'4_SNMP_trap'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'SNMP trap'],
|
|
|
|
|
'Type of information' => ['id' => 'value_type', 'value' => 'Numeric (float)'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.5:10055'],
|
|
|
|
|
'History storage period' => [
|
|
|
|
|
'radio' => ['id' => 'history_mode', 'value' => 'Do not keep history']
|
|
|
|
|
],
|
|
|
|
|
'Trend storage period' => [
|
|
|
|
|
'radio' => ['id' => 'trends_mode', 'value' => 'Storage period'],
|
|
|
|
|
'input' => ['id' => 'trends', 'value' => '99d']
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'interface_text_part' => 'SNMPv3, Context name: zabbix'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #53.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'9_SNMP_Agent',
|
|
|
|
|
'10_SNMP_Agent'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'SNMP agent'],
|
|
|
|
|
'Type of information' => ['id' => 'value_type', 'value' => 'Character'],
|
|
|
|
|
'Host interface' => ['id' => 'interface-select', 'value' => '127.0.5.5:10055']
|
|
|
|
|
],
|
|
|
|
|
'interface_text_part' => 'SNMPv3, Context name: zabbix'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #54.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'11_SSH_Agent',
|
|
|
|
|
'12_SSH_Agent'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'SSH agent'],
|
|
|
|
|
'Authentication method' => ['id' => 'authtype', 'value' => 'Public key'],
|
|
|
|
|
'User name' => ['id' => 'username', 'value' => 'new_name'],
|
|
|
|
|
'Public key file' => ['id' => 'publickey', 'value' => '/path/file1'],
|
|
|
|
|
'Private key file' => ['id' => 'privatekey', 'value' => '/path/file2']
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #55.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'11_SSH_Agent',
|
|
|
|
|
'12_SSH_Agent'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'SSH agent'],
|
|
|
|
|
'Authentication method' => ['id' => 'authtype', 'value' => 'Password'],
|
|
|
|
|
'User name' => ['id' => 'username', 'value' => 'New_user_name'],
|
|
|
|
|
'Password' => ['id' => 'password', 'value' => 'New_password']
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// #56.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'13_DB_Monitor',
|
|
|
|
|
'14_DB_Monitor'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Database monitor'],
|
|
|
|
|
'User name' => ['id' => 'username', 'value' => 'db_monitor_name'],
|
|
|
|
|
'Password' => ['id' => 'password', 'value' => 'db_monitor_password']
|
|
|
|
|
],
|
|
|
|
|
'expected_preprocessing' => [
|
|
|
|
|
'13_DB_Monitor' => [
|
|
|
|
|
[
|
|
|
|
|
'type' => 'Regular expression',
|
|
|
|
|
'parameter_1' => 'regular expression pattern',
|
|
|
|
|
'parameter_2' => 'output template',
|
|
|
|
|
'error_handler' => 'Set value to',
|
|
|
|
|
'error_handler_params' => 'Error custom value'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'14_DB_Monitor' => [
|
|
|
|
|
[
|
|
|
|
|
'type' => 'Custom multiplier',
|
|
|
|
|
'parameter_1' => '2'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// TODO: uncomment or delete after discussion
|
|
|
|
|
// [
|
|
|
|
|
// [
|
|
|
|
|
// 'names' => [
|
|
|
|
|
// '1_Item',
|
|
|
|
|
// '2_Item'
|
|
|
|
|
// ],
|
|
|
|
|
// 'change' => [
|
|
|
|
|
// 'Type' => ['id' => 'type', 'value' => 'TELNET agent'],
|
|
|
|
|
// 'User name' => ['id' => 'username', 'value' => 'telnet_name'],
|
|
|
|
|
// 'Password' => ['id' => 'password', 'value' => 'telnet_password']
|
|
|
|
|
// ]
|
|
|
|
|
// ]
|
|
|
|
|
// ],
|
|
|
|
|
// [
|
|
|
|
|
// [
|
|
|
|
|
// 'names' => [
|
|
|
|
|
// '1_Item',
|
|
|
|
|
// '2_Item'
|
|
|
|
|
// ],
|
|
|
|
|
// 'change' => [
|
|
|
|
|
// 'Type' => ['id' => 'type', 'value' => 'Calculated'],
|
|
|
|
|
// 'Type of information' => ['id' => 'value_type', 'value' => 'Numeric (float)']
|
|
|
|
|
// ]
|
|
|
|
|
// ]
|
|
|
|
|
// ],
|
|
|
|
|
// #57.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'15_Calculated',
|
|
|
|
|
'16_Calculated'
|
|
|
|
|
],
|
|
|
|
|
'change' => [
|
|
|
|
|
'Type' => ['id' => 'type', 'value' => 'Dependent item'],
|
|
|
|
|
'Master item' => ['id' => 'master_item', 'value' => '7_IPMI']
|
|
|
|
|
],
|
|
|
|
|
'expected_tags' => [
|
|
|
|
|
'15_Calculated' => [
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'Item_tag_name',
|
|
|
|
|
'value' => 'Item_tag_value'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'16_Calculated' =>[
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'Item_tag_name_1',
|
|
|
|
|
'value' => 'Item_tag_value_1'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'Item_tag_name_2',
|
|
|
|
|
'value' => 'Item_tag_value_2'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Mass update of form fields for items or item prototypes.
|
|
|
|
|
*
|
|
|
|
|
* @param array $data data provider
|
|
|
|
|
* @param boolean $prototypes true if item prototype, false if item
|
|
|
|
|
*/
|
|
|
|
|
public function executeItemsMassUpdate($data, $prototypes = false) {
|
|
|
|
|
if (CTestArrayHelper::get($data, 'expected', TEST_GOOD) === TEST_BAD) {
|
|
|
|
|
$old_hash = CDBHelper::getHash('SELECT * FROM items ORDER BY itemid');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$form = $this->openMassUpdateForm($prototypes, $data['names'])->asForm();
|
|
|
|
|
|
|
|
|
|
// Set field value.
|
|
|
|
|
foreach ($data['change'] as $field => $value) {
|
|
|
|
|
// Click on a label to show input control.
|
|
|
|
|
$form->getLabel($field)->click();
|
|
|
|
|
// Set field value.
|
|
|
|
|
switch ($field) {
|
|
|
|
|
case 'Type':
|
|
|
|
|
case 'Type of information':
|
|
|
|
|
case 'Authentication method':
|
|
|
|
|
$form->query('id', $value['id'])->asDropdown()->one()->select($value['value']);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'Host interface':
|
|
|
|
|
/**
|
|
|
|
|
* The value of an SNMP interface option element contains not only the IP and port, but also the
|
|
|
|
|
* interface type and context name or community. In this case the address and details must be merged.
|
|
|
|
|
*/
|
|
|
|
|
$interface = $value['value'].CTestArrayHelper::get($data, 'interface_text_part', '');
|
|
|
|
|
|
|
|
|
|
$form->query('id', $value['id'])->asDropdown()->one()->select($interface);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'Units':
|
|
|
|
|
case 'Description':
|
|
|
|
|
case 'User name':
|
|
|
|
|
case 'Password':
|
|
|
|
|
case 'Log time format':
|
|
|
|
|
case 'Allowed hosts':
|
|
|
|
|
case 'Request body' :
|
|
|
|
|
case 'URL':
|
|
|
|
|
case 'JMX endpoint':
|
|
|
|
|
case 'Public key file':
|
|
|
|
|
case 'Private key file':
|
|
|
|
|
case 'Timeout':
|
|
|
|
|
$form->query('id', $value['id'])->one()->fill($value['value']);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'Request body type':
|
|
|
|
|
case 'Discover':
|
|
|
|
|
case 'Enable trapping':
|
|
|
|
|
case 'Create enabled':
|
|
|
|
|
case 'Status':
|
|
|
|
|
$form->query('id', $value['id'])->one()->asSegmentedRadio()->fill($value['value']);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'Update interval':
|
|
|
|
|
$container_table = $form->query('id:update_interval')->asTable()->one();
|
|
|
|
|
$container_table->getRow(0)->getColumn(1)->query('id:delay')->one()->fill($value['Delay']);
|
|
|
|
|
|
|
|
|
|
if (array_key_exists('Custom intervals', $value)) {
|
|
|
|
|
$container_table->getRow(1)->getColumn(1)->query('id:custom_intervals')->asMultifieldTable(
|
|
|
|
|
['mapping' => self::INTERVAL_MAPPING])->one()->fill($value['Custom intervals']
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'History storage period':
|
|
|
|
|
case 'Trend storage period':
|
|
|
|
|
$form->query('id', $value['radio']['id'])->one()->asSegmentedRadio()->fill($value['radio']['value']);
|
|
|
|
|
|
|
|
|
|
if (array_key_exists('input', $value)) {
|
|
|
|
|
$form->query('id', $value['input']['id'])->one()->fill($value['input']['value']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($value['radio']['value'] === 'Do not keep history') {
|
|
|
|
|
$this->assertFalse($form->query('id:history')->one()->isVisible());
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'Headers':
|
|
|
|
|
$form->query('xpath:.//div[@id="headers_pairs"]/table')->asMultifieldTable()->one()->fill($value);
|
|
|
|
|
|
|
|
|
|
// Take a screenshot to test draggable object position of headers in mass update.
|
|
|
|
|
if (array_key_exists('screenshot', $data)) {
|
|
|
|
|
$this->page->removeFocus();
|
|
|
|
|
$this->assertScreenshot($form->query('id:headers_pairs')->waitUntilPresent()->one(), 'Item mass update headers'.$prototypes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'Master item':
|
|
|
|
|
if ($prototypes) {
|
|
|
|
|
$form->query('button:Select prototype')->one()->click();
|
|
|
|
|
$master_dialog = COverlayDialogElement::find()->all()->last()->waitUntilReady();
|
|
|
|
|
$master_dialog->query('link', $value['value'])->one()->waitUntilClickable()->click();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
$form->query('id', $value['id'])->one()->asMultiselect()
|
|
|
|
|
->setFillMode(CMultiselectElement::MODE_SELECT)->fill($value['value']);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'Value mapping':
|
|
|
|
|
$form->getField('Value mapping')->edit();
|
|
|
|
|
COverlayDialogElement::find()->one()->waitUntilReady()->query('xpath://a[text()="'.$value['value'].'"]')
|
|
|
|
|
->one()->waitUntilClickable()->click();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$this->query('button:Update')->one()->waitUntilClickable()->click();
|
|
|
|
|
$this->page->waitUntilReady();
|
|
|
|
|
|
|
|
|
|
if (CTestArrayHelper::get($data, 'expected', TEST_GOOD) === TEST_BAD) {
|
|
|
|
|
$this->assertMessage(TEST_BAD, ($prototypes ? 'Cannot update item prototypes' : 'Cannot update items'),
|
|
|
|
|
$data['details']
|
|
|
|
|
);
|
|
|
|
|
$this->assertEquals($old_hash, CDBHelper::getHash('SELECT * FROM items ORDER BY itemid'));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
$this->assertMessage(TEST_GOOD, ($prototypes ? 'Item prototypes updated' : 'Items updated'));
|
|
|
|
|
|
|
|
|
|
// Check changed fields in saved item form.
|
|
|
|
|
foreach ($data['names'] as $name) {
|
|
|
|
|
$table = $this->query('xpath://form[@name="items"]/table[@class="list-table"]')->asTable()->one();
|
|
|
|
|
$table->query('link', $name)->one()->waitUntilClickable()->click();
|
|
|
|
|
$form = $this->query('name:itemForm')->waitUntilPresent()->asForm()->one();
|
|
|
|
|
|
|
|
|
|
foreach ($data['change'] as $field => $value) {
|
|
|
|
|
switch ($field) {
|
|
|
|
|
case 'Type':
|
|
|
|
|
case 'Host interface':
|
|
|
|
|
case 'Type of information':
|
|
|
|
|
case 'Show value':
|
|
|
|
|
case 'Units':
|
|
|
|
|
case 'Description':
|
|
|
|
|
case 'Allowed hosts':
|
|
|
|
|
case 'Request body':
|
|
|
|
|
case 'URL':
|
|
|
|
|
case 'JMX endpoint':
|
|
|
|
|
case 'Authentication method':
|
|
|
|
|
case 'Public key file':
|
|
|
|
|
case 'Private key file':
|
|
|
|
|
case 'Request body type':
|
|
|
|
|
case 'User name':
|
|
|
|
|
case 'Password':
|
|
|
|
|
case 'Log time format':
|
|
|
|
|
case 'Timeout':
|
|
|
|
|
$this->assertEquals($value['value'], $form->getField($field)->getValue());
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'History storage period':
|
|
|
|
|
case 'Trend storage period':
|
|
|
|
|
if (CTestArrayHelper::get($value, 'input.value', 'null') === '0') {
|
|
|
|
|
$this->assertEquals('Do not keep '.$value['input']['id'],
|
|
|
|
|
$form->query('id',$value['radio']['id'])->one()->asSegmentedRadio()->getValue()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
$this->assertEquals($value['radio']['value'],
|
|
|
|
|
$form->query('id', $value['radio']['id'])->one()->asSegmentedRadio()->getValue()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if ($value['radio']['value'] === 'Do not keep history') {
|
|
|
|
|
$this->assertFalse($form->query('id:history')->one()->isVisible());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (array_key_exists('input', $value)) {
|
|
|
|
|
$this->assertEquals($value['input']['value'],
|
|
|
|
|
$form->query('id', $value['input']['id'])->one()->getValue()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'Status':
|
|
|
|
|
case 'Discover':
|
|
|
|
|
case 'Create enabled':
|
|
|
|
|
case 'Enable trapping':
|
|
|
|
|
$status = ($value['value'] === 'Enabled' || $value['value'] === 'Yes') ? true : false;
|
|
|
|
|
$label = ($field === 'Status') ? 'Enabled' : $field;
|
|
|
|
|
$this->assertEquals($status, $form->getField($label)->getValue());
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'Update interval':
|
|
|
|
|
$this->assertEquals($value['Delay'], $form->getField($field)->getValue());
|
|
|
|
|
if (array_key_exists('Custom intervals', $value)) {
|
|
|
|
|
// Remove action and index fields.
|
|
|
|
|
foreach($value['Custom intervals'] as &$interval) {
|
|
|
|
|
unset($interval['action'], $interval['index']);
|
|
|
|
|
}
|
|
|
|
|
unset($interval);
|
|
|
|
|
$this->assertEquals($value['Custom intervals'], $form->query('id:delayFlexTable')
|
|
|
|
|
->asMultifieldTable(['mapping' => self::INTERVAL_MAPPING])->one()->getValue()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'Headers':
|
|
|
|
|
// Remove action and index fields.
|
|
|
|
|
foreach ($value as &$header) {
|
|
|
|
|
unset($header['action'], $header['index']);
|
|
|
|
|
}
|
|
|
|
|
unset($header);
|
|
|
|
|
|
|
|
|
|
$this->assertEquals($value, $form->query('xpath:.//div[@id="headers_pairs"]/table')
|
|
|
|
|
->asMultifieldTable()->one()->getValue()
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'Master item':
|
|
|
|
|
if ($prototypes) {
|
|
|
|
|
$this->assertEquals(self::HOST_NAME.': '.$value['value'],
|
|
|
|
|
$form->query('xpath://input[@id="master_itemname"]')->one()->getValue()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
$this->assertEquals([self::HOST_NAME.': '.$value['value']],
|
|
|
|
|
$form->query('xpath://*[@id="master_itemid"]/..')->asMultiselect()->one()->getValue()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'Value mapping':
|
|
|
|
|
$this->assertEquals([$value['value']],
|
|
|
|
|
$form->query('xpath://*[@id="'.$value['id'].'"]/..')->asMultiselect()->one()->getValue()
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check that preprocessing is not changed after other fields are mass updated.
|
|
|
|
|
if (CTestArrayHelper::get($data, 'expected_preprocessing')) {
|
|
|
|
|
$form->selectTab('Preprocessing');
|
|
|
|
|
$this->assertPreprocessingSteps($data['expected_preprocessing'][$name]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check that tags are not changed after other fields are mass updated.
|
|
|
|
|
if (CTestArrayHelper::get($data, 'expected_tags')) {
|
|
|
|
|
$form->selectTab('Tags');
|
|
|
|
|
$this->query('class:tags-table')->asMultifieldTable()->one()->checkValue($data['expected_tags'][$name]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$form->query('button:Cancel')->one()->waitUntilClickable()->click();
|
|
|
|
|
$this->page->waitUntilReady();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Add items with preprocessing for mass updating.
|
|
|
|
|
*/
|
|
|
|
|
public function prepareItemPreprocessingData() {
|
|
|
|
|
CDataHelper::call('item.create', [
|
|
|
|
|
[
|
|
|
|
|
'hostid' => self::HOSTID,
|
|
|
|
|
'name' => '1_Item_Preprocessing',
|
|
|
|
|
'key_' => '1agent.preproc',
|
|
|
|
|
'type' => 0,
|
|
|
|
|
'value_type' => 0,
|
|
|
|
|
'interfaceid' => self::AGENT_INTERFACE_ID,
|
|
|
|
|
'delay' => '1m',
|
|
|
|
|
'preprocessing' => [
|
|
|
|
|
[
|
|
|
|
|
'type' => '4',
|
|
|
|
|
'params' => '123',
|
|
|
|
|
'error_handler' => 0,
|
|
|
|
|
'error_handler_params' => ''
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'type' => '25',
|
|
|
|
|
'params' => "error\nmistake",
|
|
|
|
|
'error_handler' => 0,
|
|
|
|
|
'error_handler_params' => ''
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'hostid' => self::HOSTID,
|
|
|
|
|
'name' => '2_Item_Preprocessing',
|
|
|
|
|
'key_' => '2agent.preproc',
|
|
|
|
|
'type' => 0,
|
|
|
|
|
'value_type' => 1,
|
|
|
|
|
'interfaceid' => self::AGENT_INTERFACE_ID,
|
|
|
|
|
'delay' => '2m',
|
|
|
|
|
'preprocessing' => [
|
|
|
|
|
[
|
|
|
|
|
'type' => '5',
|
|
|
|
|
'params' => "pattern\noutput",
|
|
|
|
|
'error_handler' => 2,
|
|
|
|
|
'error_handler_params' => 'custom_value'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'type' => '16',
|
|
|
|
|
'params' => '$path',
|
|
|
|
|
'error_handler' => 3,
|
|
|
|
|
'error_handler_params' => 'custom_error'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'hostid' => self::HOSTID,
|
|
|
|
|
'name' => '1_Item_No_Preprocessing',
|
|
|
|
|
'key_' => '1agent.no.preproc',
|
|
|
|
|
'type' => 0,
|
|
|
|
|
'value_type' => 0,
|
|
|
|
|
'interfaceid' => self::AGENT_INTERFACE_ID,
|
|
|
|
|
'delay' => '1m'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'hostid' => self::HOSTID,
|
|
|
|
|
'name' => '2_Item_No_Preprocessing',
|
|
|
|
|
'key_' => '2agent.no.preproc',
|
|
|
|
|
'type' => 0,
|
|
|
|
|
'value_type' => 1,
|
|
|
|
|
'interfaceid' => self::AGENT_INTERFACE_ID,
|
|
|
|
|
'delay' => '2m'
|
|
|
|
|
]
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getCommonPreprocessingChangeData() {
|
|
|
|
|
return [
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_Tags_Preprocessing',
|
|
|
|
|
'1_Item_No_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Preprocessing steps' => [
|
|
|
|
|
['type' => 'Custom multiplier', 'parameter_1' => 'abc']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/preprocessing/1/params/1": a floating point value is expected.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_Tags_Preprocessing',
|
|
|
|
|
'1_Item_No_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Preprocessing steps' => [
|
|
|
|
|
['type' => 'Simple change'],
|
|
|
|
|
['type' => 'Simple change']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/preprocessing/2": only one object can exist within the '.
|
|
|
|
|
'combinations of (type)=((9, 10)).'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_Tags_Preprocessing',
|
|
|
|
|
'1_Item_No_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Preprocessing steps' => [
|
|
|
|
|
['type' => 'In range', 'parameter_1' => '8', 'parameter_2' => '-8']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/preprocessing/1/params/2": cannot be less than or equal to '.
|
|
|
|
|
'the value of parameter "/1/preprocessing/1/params/1".'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_Tags_Preprocessing',
|
|
|
|
|
'1_Item_No_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Preprocessing steps' => [
|
|
|
|
|
['type' => 'Check for error using regular expression', 'parameter_1' => 'test']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/preprocessing/1/params/2": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_Tags_Preprocessing',
|
|
|
|
|
'1_Item_No_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Preprocessing steps' => [
|
|
|
|
|
['type' => 'Discard unchanged'],
|
|
|
|
|
['type' => 'Discard unchanged with heartbeat', 'parameter_1' => '1']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/preprocessing/2": only one object can exist within the '.
|
|
|
|
|
'combinations of (type)=((19, 20)).'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_Tags_Preprocessing',
|
|
|
|
|
'1_Item_No_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Preprocessing steps' => [
|
|
|
|
|
['type' => 'Regular expression']
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/preprocessing/1/params/1": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'2_Item_Tags_Preprocessing',
|
|
|
|
|
'2_Item_No_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Preprocessing steps' => [
|
|
|
|
|
[
|
|
|
|
|
'type' => 'XML XPath',
|
|
|
|
|
'parameter_1' => "//path/one",
|
|
|
|
|
'on_fail' => true,
|
|
|
|
|
'error_handler' => 'Set error to'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/preprocessing/1/error_handler_params": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_Tags_Preprocessing',
|
|
|
|
|
'2_Item_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Preprocessing steps' => []
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_Tags_Preprocessing',
|
|
|
|
|
'1_Item_No_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Preprocessing steps' => [
|
|
|
|
|
[
|
|
|
|
|
'type' => 'Custom multiplier',
|
|
|
|
|
'parameter_1' => '3',
|
|
|
|
|
'on_fail' => true,
|
|
|
|
|
'error_handler' => 'Set error to',
|
|
|
|
|
'error_handler_params' => 'New_error1'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'type' => 'In range',
|
|
|
|
|
'parameter_1' => '10',
|
|
|
|
|
'parameter_2' => '20',
|
|
|
|
|
'on_fail' => true,
|
|
|
|
|
'error_handler' => 'Set value to',
|
|
|
|
|
'error_handler_params' => 'New_value_2'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'type' => 'JSONPath',
|
|
|
|
|
'parameter_1' => '$path',
|
|
|
|
|
'on_fail' => true,
|
|
|
|
|
'error_handler' => 'Discard value'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'type' => 'Discard unchanged'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_Tags_Preprocessing',
|
|
|
|
|
'2_Item_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Preprocessing steps' => [
|
|
|
|
|
['type' => 'Replace', 'parameter_1' => 'text', 'parameter_2' => 'REPLACEMENT'],
|
|
|
|
|
['type' => 'Right trim', 'parameter_1' => 'abc'],
|
|
|
|
|
['type' => 'Left trim', 'parameter_1' => 'def'],
|
|
|
|
|
['type' => 'Trim', 'parameter_1' => '1a2b3c'],
|
|
|
|
|
['type' => 'CSV to JSON','parameter_1' => ' ', 'parameter_2' => '\\', 'parameter_3' => true],
|
|
|
|
|
['type' => 'Custom multiplier', 'parameter_1' => '123'],
|
|
|
|
|
['type' => 'Regular expression', 'parameter_1' => 'expression', 'parameter_2' => 'test output'],
|
|
|
|
|
['type' => 'Boolean to decimal'],
|
|
|
|
|
['type' => 'Octal to decimal'],
|
|
|
|
|
['type' => 'Hexadecimal to decimal'],
|
|
|
|
|
['type' => 'JavaScript', 'parameter_1' => 'Test JavaScript'],
|
|
|
|
|
['type' => 'Simple change'],
|
|
|
|
|
['type' => 'In range', 'parameter_1' => '-5', 'parameter_2' => '9.5'],
|
|
|
|
|
['type' => 'Discard unchanged with heartbeat', 'parameter_1' => '5'],
|
|
|
|
|
['type' => 'Prometheus pattern', 'parameter_1' => 'cpu_usage_system', 'parameter_2' => 'label',
|
|
|
|
|
'parameter_3' => 'label_name']
|
|
|
|
|
],
|
|
|
|
|
'Screenshot' => true
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Mass update of preprocessing steps for items or item prototypes.
|
|
|
|
|
*
|
|
|
|
|
* @param array $data data provider
|
|
|
|
|
* @param boolean $prototypes true if item prototype, false if item
|
|
|
|
|
*/
|
|
|
|
|
public function executeItemsPreprocessingMassUpdate($data, $prototypes = false) {
|
|
|
|
|
if (CTestArrayHelper::get($data, 'expected', TEST_GOOD) === TEST_BAD) {
|
|
|
|
|
$old_hash = CDBHelper::getHash('SELECT * FROM items ORDER BY itemid');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$dialog = $this->openMassUpdateForm($prototypes, $data['names']);
|
|
|
|
|
$form = $dialog->asForm();
|
|
|
|
|
$form->selectTab('Preprocessing');
|
|
|
|
|
$form->getLabel('Preprocessing steps')->click();
|
|
|
|
|
|
|
|
|
|
if ($data['Preprocessing steps'] !== []) {
|
|
|
|
|
$this->addPreprocessingSteps($data['Preprocessing steps']);
|
|
|
|
|
|
|
|
|
|
// Take a screenshot to test draggable object position of preprocessing steps in mass update.
|
|
|
|
|
if (array_key_exists('Screenshot', $data)) {
|
|
|
|
|
$this->page->removeFocus();
|
|
|
|
|
|
|
|
|
|
// It is necessary because of unexpected viewport shift.
|
|
|
|
|
$this->page->updateViewport();
|
|
|
|
|
$this->assertScreenshot($form->query('id:preprocessing')->waitUntilPresent()->one(), 'Item mass update preprocessing'.$prototypes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$dialog->query('button:Update')->one()->waitUntilClickable()->click();
|
|
|
|
|
$this->page->waitUntilReady();
|
|
|
|
|
|
|
|
|
|
if (CTestArrayHelper::get($data, 'expected', TEST_GOOD) === TEST_BAD) {
|
|
|
|
|
$error = $prototypes ? 'Cannot update item prototypes' : 'Cannot update items';
|
|
|
|
|
$this->assertMessage(TEST_BAD, $error, $data['details']);
|
|
|
|
|
$this->assertEquals($old_hash, CDBHelper::getHash('SELECT * FROM items ORDER BY itemid'));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
$this->assertMessage(TEST_GOOD, ($prototypes ? 'Item prototypes updated' : 'Items updated'));
|
|
|
|
|
|
|
|
|
|
// Check changed fields in saved item form.
|
|
|
|
|
foreach ($data['names'] as $name) {
|
|
|
|
|
$table = $this->query('xpath://form[@name="items"]/table[@class="list-table"]')->asTable()->one();
|
|
|
|
|
// TODO: not stable test testPageMassUpdateItems_ChangePreprocessing#8 on Jenkins, failed to properly waitUntilReady for page
|
|
|
|
|
try {
|
|
|
|
|
$table->query('link', $name)->one()->waitUntilClickable()->click();
|
|
|
|
|
}
|
|
|
|
|
catch (ElementClickInterceptedException $e) {
|
|
|
|
|
$table->query('link', $name)->one()->waitUntilClickable()->click();
|
|
|
|
|
}
|
|
|
|
|
$form = $this->query('name:itemForm')->waitUntilPresent()->asForm()->one();
|
|
|
|
|
$form->selectTab('Preprocessing');
|
|
|
|
|
$this->assertPreprocessingSteps($data['Preprocessing steps']);
|
|
|
|
|
$form->query('button:Cancel')->one()->waitUntilClickable()->click();
|
|
|
|
|
$this->page->waitUntilReady();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getCommonTagsChangeData() {
|
|
|
|
|
return [
|
|
|
|
|
// Empty tag name.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_Tags_Preprocessing',
|
|
|
|
|
'1_Item_No_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Tags' => [
|
|
|
|
|
'action' => 'Add',
|
|
|
|
|
'tags' => [
|
|
|
|
|
[
|
|
|
|
|
'action' => USER_ACTION_UPDATE,
|
|
|
|
|
'index' => 0,
|
|
|
|
|
'value' => 'value1'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/tags/2/tag": cannot be empty.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// TODO: Uncomment this case when ZBX-19263 is fixed.
|
|
|
|
|
// Equal tags.
|
|
|
|
|
/*
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'expected' => TEST_BAD,
|
|
|
|
|
'names' => [
|
|
|
|
|
'2_Item_Tags_Preprocessing',
|
|
|
|
|
'2_Item_No_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Tags' => [
|
|
|
|
|
[
|
|
|
|
|
'action' => USER_ACTION_UPDATE,
|
|
|
|
|
'index' => 0,
|
|
|
|
|
'tag' => 'tag',
|
|
|
|
|
'value' => 'value'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'tag',
|
|
|
|
|
'value' => 'value'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'details' => 'Invalid parameter "/1/tags/2": value (tag, value)=(tag, value) already exists.'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
*/
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_Tags_Preprocessing',
|
|
|
|
|
'2_Item_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Tags' => [
|
|
|
|
|
'action' => 'Add',
|
|
|
|
|
'tags' => []
|
|
|
|
|
],
|
|
|
|
|
'expected_tags' => [
|
|
|
|
|
'1_Item_Tags_Preprocessing' => [
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'old_tag_1',
|
|
|
|
|
'value' => 'old_value_1'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'2_Item_Tags_Preprocessing' => [
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'old_tag_2',
|
|
|
|
|
'value' => 'old_value_2'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'old_tag_3',
|
|
|
|
|
'value' => 'old_value_3'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_Tags_Preprocessing',
|
|
|
|
|
'2_Item_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Tags' => [
|
|
|
|
|
'action' => 'Add',
|
|
|
|
|
'tags' => [
|
|
|
|
|
[
|
|
|
|
|
'action' => USER_ACTION_UPDATE,
|
|
|
|
|
'index' => 0,
|
|
|
|
|
'tag' => 'added_tag_1',
|
|
|
|
|
'value' => 'added_value_1'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'expected_tags' => [
|
|
|
|
|
'1_Item_Tags_Preprocessing' => [
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'added_tag_1',
|
|
|
|
|
'value' => 'added_value_1'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'old_tag_1',
|
|
|
|
|
'value' => 'old_value_1'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'2_Item_Tags_Preprocessing' => [
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'added_tag_1',
|
|
|
|
|
'value' => 'added_value_1'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'old_tag_2',
|
|
|
|
|
'value' => 'old_value_2'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'old_tag_3',
|
|
|
|
|
'value' => 'old_value_3'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_Tags_replace',
|
|
|
|
|
'2_Item_Tags_replace'
|
|
|
|
|
],
|
|
|
|
|
'Tags' => [
|
|
|
|
|
'action' => 'Replace',
|
|
|
|
|
'tags' => []
|
|
|
|
|
],
|
|
|
|
|
'expected_tags' => [
|
|
|
|
|
'1_Item_Tags_replace' => [
|
|
|
|
|
[
|
|
|
|
|
'tag' => '',
|
|
|
|
|
'value' => ''
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'2_Item_Tags_replace' => [
|
|
|
|
|
[
|
|
|
|
|
'tag' => '',
|
|
|
|
|
'value' => ''
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_Tags_replace',
|
|
|
|
|
'2_Item_Tags_replace'
|
|
|
|
|
],
|
|
|
|
|
'Tags' => [
|
|
|
|
|
'action' => 'Replace',
|
|
|
|
|
'tags' => [
|
|
|
|
|
[
|
|
|
|
|
'action' => USER_ACTION_UPDATE,
|
|
|
|
|
'index' => 0,
|
|
|
|
|
'tag' => 'replaced_tag',
|
|
|
|
|
'value' => 'replaced_value'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'expected_tags' => [
|
|
|
|
|
'1_Item_Tags_replace' => [
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'replaced_tag',
|
|
|
|
|
'value' => 'replaced_value'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'2_Item_Tags_replace' => [
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'replaced_tag',
|
|
|
|
|
'value' => 'replaced_value'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_Tags_remove',
|
|
|
|
|
'2_Item_Tags_remove'
|
|
|
|
|
],
|
|
|
|
|
'Tags' => [
|
|
|
|
|
'action' => 'Remove',
|
|
|
|
|
'tags' => [
|
|
|
|
|
[
|
|
|
|
|
'tag' => '',
|
|
|
|
|
'value' => ''
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'expected_tags' => [
|
|
|
|
|
'1_Item_Tags_remove' => [
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'remove_tag_1',
|
|
|
|
|
'value' => 'remove_value_1'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'remove_tag_2',
|
|
|
|
|
'value' => 'remove_value_2'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'2_Item_Tags_remove' => [
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'remove_tag_2',
|
|
|
|
|
'value' => 'remove_value_2'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_Tags_remove',
|
|
|
|
|
'2_Item_Tags_remove',
|
|
|
|
|
'3_Item_Tags_remove'
|
|
|
|
|
],
|
|
|
|
|
'Tags' => [
|
|
|
|
|
'action' => 'Remove',
|
|
|
|
|
'tags' => [
|
|
|
|
|
[
|
|
|
|
|
'action' => USER_ACTION_UPDATE,
|
|
|
|
|
'index' => 0,
|
|
|
|
|
'tag' => 'remove_tag_2',
|
|
|
|
|
'value' => 'remove_value_2'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'expected_tags' => [
|
|
|
|
|
'1_Item_Tags_remove' => [
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'remove_tag_1',
|
|
|
|
|
'value' => 'remove_value_1'
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'2_Item_Tags_remove' => [
|
|
|
|
|
[
|
|
|
|
|
'tag' => '',
|
|
|
|
|
'value' => ''
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'3_Item_Tags_remove' => [
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'remove_tag_3',
|
|
|
|
|
'value' => 'remove_value_3'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// Different symbols in tag names and values.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_No_Tags_Preprocessing',
|
|
|
|
|
'2_Item_No_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Tags' => [
|
|
|
|
|
'action' => 'Add',
|
|
|
|
|
'tags' => [
|
|
|
|
|
[
|
|
|
|
|
'action' => USER_ACTION_UPDATE,
|
|
|
|
|
'index' => 0,
|
|
|
|
|
'tag' => '!@#$%^&*()_+<>,.\/',
|
|
|
|
|
'value' => '!@#$%^&*()_+<>,.\/'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'tag1',
|
|
|
|
|
'value' => 'value1'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'tag2'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'tag' => '{$MACRO:A}',
|
|
|
|
|
'value' => '{$MACRO:A}'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'tag' => '{$MACRO}',
|
|
|
|
|
'value' => '{$MACRO}'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'Таг',
|
|
|
|
|
'value' => 'Значение'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// Two tags with equal tag names.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_No_Tags_Preprocessing',
|
|
|
|
|
'2_Item_No_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Tags' => [
|
|
|
|
|
'action' => 'Replace',
|
|
|
|
|
'tags' => [
|
|
|
|
|
[
|
|
|
|
|
'action' => USER_ACTION_UPDATE,
|
|
|
|
|
'index' => 0,
|
|
|
|
|
'tag' => 'tag3',
|
|
|
|
|
'value' => '3'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'tag3',
|
|
|
|
|
'value' => '4'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// Two tags with equal tag values.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_No_Tags_Preprocessing',
|
|
|
|
|
'2_Item_No_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Tags' => [
|
|
|
|
|
'action' => 'Replace',
|
|
|
|
|
'tags' => [
|
|
|
|
|
[
|
|
|
|
|
'action' => USER_ACTION_UPDATE,
|
|
|
|
|
'index' => 0,
|
|
|
|
|
'tag' => 'tag4',
|
|
|
|
|
'value' => '5'
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'tag' => 'tag5',
|
|
|
|
|
'value' => '5'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// Tag with trailing spaces.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_No_Tags_Preprocessing',
|
|
|
|
|
'2_Item_No_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Tags' => [
|
|
|
|
|
'action' => 'Replace',
|
|
|
|
|
'tags' => [
|
|
|
|
|
[
|
|
|
|
|
'action' => USER_ACTION_UPDATE,
|
|
|
|
|
'index' => 0,
|
|
|
|
|
'tag' => ' trimmed tag ',
|
|
|
|
|
'value' => ' trimmed value '
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
'trim' => true
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
// Tag with long name and value.
|
|
|
|
|
[
|
|
|
|
|
[
|
|
|
|
|
'names' => [
|
|
|
|
|
'1_Item_No_Tags_Preprocessing',
|
|
|
|
|
'2_Item_No_Tags_Preprocessing'
|
|
|
|
|
],
|
|
|
|
|
'Tags' => [
|
|
|
|
|
'action' => 'Replace',
|
|
|
|
|
'tags' => [
|
|
|
|
|
[
|
|
|
|
|
'action' => USER_ACTION_UPDATE,
|
|
|
|
|
'index' => 0,
|
|
|
|
|
'tag' => 'Long tag name. Long tag name. Long tag name. Long tag name. Long tag name.'.
|
|
|
|
|
' Long tag name. Long tag name. Long tag name.',
|
|
|
|
|
'value' => 'Long tag value. Long tag value. Long tag value. Long tag value. Long tag value.'.
|
|
|
|
|
' Long tag value. Long tag value. Long tag value. Long tag value.'
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Mass update of items or item prototypes tags.
|
|
|
|
|
*
|
|
|
|
|
* @param array $data data provider
|
|
|
|
|
* @param boolean $prototypes true if item prototype, false if item
|
|
|
|
|
*/
|
|
|
|
|
public function executeItemsTagsMassUpdate($data, $prototypes = false) {
|
|
|
|
|
if (CTestArrayHelper::get($data, 'expected', TEST_GOOD) === TEST_BAD) {
|
|
|
|
|
$old_hash = CDBHelper::getHash('SELECT * FROM items ORDER BY itemid');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$dialog = $this->openMassUpdateForm($prototypes, $data['names']);
|
|
|
|
|
$form = $dialog->asForm();
|
|
|
|
|
$form->selectTab('Tags');
|
|
|
|
|
$form->getLabel('Tags')->click();
|
|
|
|
|
|
|
|
|
|
$form->query('id:mass_update_tags')->asSegmentedRadio()->one()->fill($data['Tags']['action']);
|
|
|
|
|
|
|
|
|
|
if ($data['Tags']['tags'] !== []) {
|
|
|
|
|
$this->query('class:tags-table')->asMultifieldTable()->one()->fill($data['Tags']['tags']);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$dialog->query('button:Update')->one()->waitUntilClickable()->click();
|
|
|
|
|
$this->page->waitUntilReady();
|
|
|
|
|
|
|
|
|
|
if (CTestArrayHelper::get($data, 'expected', TEST_GOOD) === TEST_BAD) {
|
|
|
|
|
$error = $prototypes ? 'Cannot update item prototypes' : 'Cannot update items';
|
|
|
|
|
$this->assertMessage(TEST_BAD, $error, $data['details']);
|
|
|
|
|
$this->assertEquals($old_hash, CDBHelper::getHash('SELECT * FROM items ORDER BY itemid'));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
$this->assertMessage(TEST_GOOD, ($prototypes ? 'Item prototypes updated' : 'Items updated'));
|
|
|
|
|
|
|
|
|
|
// Check changed fields in saved item form.
|
|
|
|
|
foreach ($data['names'] as $name) {
|
|
|
|
|
$table = $this->query('xpath://form[@name="items"]/table[@class="list-table"]')->asTable()->one();
|
|
|
|
|
$table->query('link', $name)->one()->waitUntilClickable()->click();
|
|
|
|
|
$form = $this->query('name:itemForm')->waitUntilPresent()->asForm()->one();
|
|
|
|
|
$form->selectTab('Tags');
|
|
|
|
|
|
|
|
|
|
$expected = $data['Tags']['tags'];
|
|
|
|
|
if (!array_key_exists('expected_tags', $data)) {
|
|
|
|
|
// Remove action and index fields for asserting expected result.
|
|
|
|
|
foreach ($expected as &$tag) {
|
|
|
|
|
unset($tag['action'], $tag['index']);
|
|
|
|
|
|
|
|
|
|
if (CTestArrayHelper::get($data, 'trim', false) === false) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Remove trailing spaces from tag and value for asserting expected result.
|
|
|
|
|
foreach ($expected as $i => &$options) {
|
|
|
|
|
foreach (['tag', 'value'] as $parameter) {
|
|
|
|
|
if (array_key_exists($parameter, $options)) {
|
|
|
|
|
$options[$parameter] = trim($options[$parameter]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
unset($options);
|
|
|
|
|
}
|
|
|
|
|
unset($tag);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$expected_tags = array_key_exists('expected_tags', $data) ? $data['expected_tags'][$name] : $expected;
|
|
|
|
|
$this->query('class:tags-table')->asMultifieldTable()->one()->checkValue($expected_tags);
|
|
|
|
|
|
|
|
|
|
$form->query('button:Cancel')->one()->waitUntilClickable()->click();
|
|
|
|
|
$this->page->waitUntilReady();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Cancel Mass updating of items or item prototypes.
|
|
|
|
|
*
|
|
|
|
|
* @param boolean $prototypes true if item prototype, false if item
|
|
|
|
|
*/
|
|
|
|
|
public function executeMassUpdateCancel($prototypes = false) {
|
|
|
|
|
$old_hash = CDBHelper::getHash('SELECT * FROM items ORDER BY itemid');
|
|
|
|
|
|
|
|
|
|
$items = [
|
|
|
|
|
'1_Item_Tags_Preprocessing',
|
|
|
|
|
'2_Item_Tags_Preprocessing',
|
|
|
|
|
'1_Item_No_Tags_Preprocessing',
|
|
|
|
|
'2_Item_No_Tags_Preprocessing'
|
|
|
|
|
];
|
|
|
|
|
$dialog = $this->openMassUpdateForm($prototypes, $items);
|
|
|
|
|
$dialog->query('button:Cancel')->one()->waitUntilClickable()->click();
|
|
|
|
|
|
|
|
|
|
// Check that UI returned to previous page and hash remained unchanged.
|
|
|
|
|
$this->page->waitUntilReady();
|
|
|
|
|
$this->page->assertHeader($prototypes ? 'Item prototypes' : 'Items');
|
|
|
|
|
$this->assertEquals($old_hash, CDBHelper::getHash('SELECT * FROM items ORDER BY itemid'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Select items or item prototypes in list and open Mass update form.
|
|
|
|
|
*
|
|
|
|
|
* @param boolean $prototypes true if item prototype, false if item
|
|
|
|
|
* @param array $data items to be mass updated
|
|
|
|
|
*
|
|
|
|
|
* @return CElement
|
|
|
|
|
*/
|
|
|
|
|
private function openMassUpdateForm($prototypes, $data) {
|
|
|
|
|
$link = ($prototypes)
|
|
|
|
|
? 'disc_prototypes.php?parent_discoveryid='.self::RULEID.'&context=host'
|
|
|
|
|
: 'items.php?filter_set=1&filter_hostids%5B0%5D='.self::HOSTID.'&context=host';
|
|
|
|
|
$this->page->login()->open($link);
|
|
|
|
|
|
|
|
|
|
// Get item table.
|
|
|
|
|
$table = $this->query('xpath://form[@name="items"]/table[@class="list-table"]')->asTable()->one();
|
|
|
|
|
$table->findRows('Name', $data)->select();
|
|
|
|
|
|
|
|
|
|
// Open mass update form.
|
|
|
|
|
$this->query('button:Mass update')->one()->click();
|
|
|
|
|
|
|
|
|
|
return COverlayDialogElement::find()->one()->waitUntilReady();
|
|
|
|
|
}
|
|
|
|
|
}
|