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.

2301 lines
62 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?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();
}
}