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.
2233 lines
61 KiB
2233 lines
61 KiB
1 year ago
|
<?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__).'/../behaviors/CMessageBehavior.php';
|
||
|
require_once dirname(__FILE__).'/../../include/helpers/CDataHelper.php';
|
||
|
require_once dirname(__FILE__).'/../traits/TableTrait.php';
|
||
|
|
||
|
/**
|
||
|
* Base class for Host form tests.
|
||
|
*/
|
||
|
class testFormHost extends CWebTest {
|
||
|
|
||
|
use TableTrait;
|
||
|
|
||
|
/**
|
||
|
* All objects created in dataSource DiscoveredHosts.
|
||
|
*/
|
||
|
const DISCOVERED_HOST = 'Discovered host from prototype 1'; // "LLD for Discovered host tests", Host: "Test of discovered host".
|
||
|
const TEMPLATE_NAMES = [
|
||
|
'Test of discovered host 1 template for unlink',
|
||
|
'Test of discovered host 2 template for clear',
|
||
|
'Test of discovered host Template'
|
||
|
];
|
||
|
|
||
|
/**
|
||
|
* Attach Behaviors to the test.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getBehaviors() {
|
||
|
return ['class' => CMessageBehavior::class];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Link to page for opening host form.
|
||
|
*/
|
||
|
public $link;
|
||
|
|
||
|
/**
|
||
|
* Flag for host form opened by direct link.
|
||
|
*/
|
||
|
public $standalone = false;
|
||
|
|
||
|
/**
|
||
|
* Flag for form opened from Monitoring -> Hosts section.
|
||
|
*/
|
||
|
public $monitoring = false;
|
||
|
|
||
|
/**
|
||
|
* SQL query to get host and host interfaces tables to compare hash values.
|
||
|
*/
|
||
|
private $hosts_sql = 'SELECT * FROM hosts h INNER JOIN interface i ON h.hostid=i.hostid ORDER BY h.hostid, i.interfaceid';
|
||
|
|
||
|
/**
|
||
|
* SQL query to get snmp interface table to compare hash values.
|
||
|
*/
|
||
|
private $interface_snmp_sql = 'SELECT * FROM interface_snmp ORDER BY interfaceid, community';
|
||
|
|
||
|
/**
|
||
|
* Ids of the hosts that are created within this test specifically for the update scenario.
|
||
|
*
|
||
|
* @var array
|
||
|
*/
|
||
|
protected static $hostids;
|
||
|
|
||
|
/**
|
||
|
* Ids of the items that are created within this test.
|
||
|
*
|
||
|
* @var array
|
||
|
*/
|
||
|
protected static $itemids;
|
||
|
|
||
|
/**
|
||
|
* Default values of interfaces.
|
||
|
*
|
||
|
* @var array
|
||
|
*/
|
||
|
private $default_values = [
|
||
|
'Agent' => [
|
||
|
'ip' => '127.0.0.1',
|
||
|
'dns' => '',
|
||
|
'Connect to' => 'IP',
|
||
|
'port' => 10050
|
||
|
],
|
||
|
'SNMP' => [
|
||
|
'ip' => '127.0.0.1',
|
||
|
'dns' => '',
|
||
|
'Connect to' => 'IP',
|
||
|
'port' => 161,
|
||
|
'SNMP version' => 'SNMPv2',
|
||
|
'SNMP community' => '{$SNMP_COMMUNITY}',
|
||
|
'Use combined requests' => true
|
||
|
],
|
||
|
'JMX' => [
|
||
|
'ip' => '127.0.0.1',
|
||
|
'dns' => '',
|
||
|
'Connect to' => 'IP',
|
||
|
'port' => 12345
|
||
|
],
|
||
|
'IPMI' => [
|
||
|
'ip' => '127.0.0.1',
|
||
|
'dns' => '',
|
||
|
'Connect to' => 'IP',
|
||
|
'port' => 623
|
||
|
]
|
||
|
];
|
||
|
|
||
|
public static function prepareUpdateData() {
|
||
|
$interfaces = [
|
||
|
[
|
||
|
'type' => 1,
|
||
|
'main' => 1,
|
||
|
'useip' => 1,
|
||
|
'ip' => '127.1.1.1',
|
||
|
'dns' => '',
|
||
|
'port' => '10011'
|
||
|
],
|
||
|
[
|
||
|
'type' => 2,
|
||
|
'main' => 1,
|
||
|
'useip' => 1,
|
||
|
'ip' => '127.2.2.2',
|
||
|
'dns' => '',
|
||
|
'port' => 122,
|
||
|
'details' => [
|
||
|
'version' => 1,
|
||
|
'bulk' => 0,
|
||
|
'community' => '🙃zabbix🙃'
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
'type' => 3,
|
||
|
'main' => 1,
|
||
|
'useip' => 0,
|
||
|
'ip' => '',
|
||
|
'dns' => 'selenium.test',
|
||
|
'port' => 30053
|
||
|
],
|
||
|
[
|
||
|
'type' => 4,
|
||
|
'main' => 1,
|
||
|
'useip' => 1,
|
||
|
'ip' => '127.4.4.4',
|
||
|
'dns' => '',
|
||
|
'port' => 426
|
||
|
]
|
||
|
];
|
||
|
|
||
|
$groups = [
|
||
|
[
|
||
|
'groupid' => 4
|
||
|
]
|
||
|
];
|
||
|
|
||
|
$result = CDataHelper::createHosts([
|
||
|
[
|
||
|
'host' => 'testFormHost_Update',
|
||
|
'name' => 'testFormHost_Update Visible name',
|
||
|
'description' => 'Created host via API to test update functionality in host form and interfaces',
|
||
|
'interfaces' => $interfaces,
|
||
|
'groups' => $groups,
|
||
|
'proxyid' => 20000,
|
||
|
'status' => HOST_STATUS_MONITORED
|
||
|
],
|
||
|
[
|
||
|
'host' => 'testFormHost with items',
|
||
|
'description' => 'Created host via API to test clone functionality in host form and interfaces 😀',
|
||
|
'interfaces' => $interfaces,
|
||
|
'groups' => $groups,
|
||
|
'proxyid' => 20000,
|
||
|
'status' => HOST_STATUS_NOT_MONITORED,
|
||
|
'items' => [
|
||
|
[
|
||
|
'name' => 'Agent active item',
|
||
|
'key_' => 'agent.ping',
|
||
|
'type' => ITEM_TYPE_ZABBIX_ACTIVE,
|
||
|
'value_type' => ITEM_VALUE_TYPE_UINT64,
|
||
|
'delay' => '1m'
|
||
|
],
|
||
|
[
|
||
|
'name' => 'Agent item',
|
||
|
'key_' => 'agent.hostname',
|
||
|
'type' => ITEM_TYPE_ZABBIX,
|
||
|
'value_type' => ITEM_VALUE_TYPE_UINT64,
|
||
|
'delay' => '1h'
|
||
|
],
|
||
|
[
|
||
|
'name' => 'JMX item',
|
||
|
'key_' => 'jmx[object_name,attribute_name]',
|
||
|
'type' => ITEM_TYPE_JMX,
|
||
|
'value_type' => ITEM_VALUE_TYPE_TEXT,
|
||
|
'delay' => '1s',
|
||
|
'username' => '',
|
||
|
'password' => ''
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
'host' => 'testFormHost with secret Macro',
|
||
|
'groups' => $groups,
|
||
|
'macros' => [
|
||
|
[
|
||
|
'macro' => '{$USER_MACRO}',
|
||
|
'value' => 'secret',
|
||
|
'description' => 'secret text',
|
||
|
'type' => '1'
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]);
|
||
|
|
||
|
self::$hostids = $result['hostids'];
|
||
|
self::$itemids = $result['itemids'];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test for checking host form layout.
|
||
|
*/
|
||
|
public function checkHostLayout() {
|
||
|
$host = 'testFormHost with items';
|
||
|
$hostid = CDBHelper::getValue('SELECT hostid FROM hosts WHERE name='.zbx_dbstr($host));
|
||
|
|
||
|
$form = $this->openForm(($this->standalone ? $this->link.$hostid : $this->link), $host);
|
||
|
|
||
|
// Check tabs available in the form.
|
||
|
$tabs = ['Host', 'IPMI', 'Tags', 'Macros', 'Inventory', 'Encryption', 'Value mapping'];
|
||
|
$this->assertEquals(count($tabs), $form->query('xpath:.//li[@role="tab"]')->all()->count());
|
||
|
foreach ($tabs as $tab) {
|
||
|
$this->assertTrue($form->query("xpath:.//li[@role='tab']//a[text()=".CXPathHelper::escapeQuotes($tab)."]")
|
||
|
->one()->isValid()
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// Host form fields maxlength attribute.
|
||
|
foreach (['Host name' => 128, 'Visible name' => 128, 'Description' => 65535] as $field => $maxlength) {
|
||
|
$this->assertEquals($maxlength, $form->getField($field)->getAttribute('maxlength'));
|
||
|
}
|
||
|
|
||
|
$interfaces_form = $form->getFieldContainer('Interfaces')->asHostInterfaceElement();
|
||
|
$this->assertEquals(['', 'Type', 'IP address', 'DNS name', 'Connect to', 'Port', 'Default'],
|
||
|
$interfaces_form->getHeadersText()
|
||
|
);
|
||
|
|
||
|
foreach ($interfaces_form->getRows() as $i => $row) {
|
||
|
$enabled = ($i !== 0 && $i !== 2);
|
||
|
// "Remove" button is disabled (in the 7th column) for Agent (in 0th row) and JMX (in 2nd row) interfaces.
|
||
|
$this->assertTrue($row->getColumn(7)->query('tag:button')->one()->isEnabled($enabled));
|
||
|
}
|
||
|
// Interface fields maxlength attribute.
|
||
|
foreach (['IP address' => 64, 'DNS name' => 255, 'Port' => 64] as $field => $maxlength) {
|
||
|
$this->assertEquals($maxlength, $interfaces_form->getRow(0)->getColumn($field)
|
||
|
->query('tag:input')->one()->getAttribute('maxlength')
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// Click the "expand" icon (in the 0th column) for the SNMP interface (1st row).
|
||
|
$interfaces_form->getRow(1)->getColumn(0)->query('tag:button')->one()->click();
|
||
|
$snmp_form = $interfaces_form->getRow(1)->query('xpath:.//div[@class="form-grid"]')->one()->parents()
|
||
|
->asGridForm(['normalized' => true])->one();
|
||
|
$data = [
|
||
|
'SNMPv1' => ['SNMP version', 'SNMP community', 'Use combined requests'],
|
||
|
'SNMPv2' => ['SNMP version', 'SNMP community', 'Max repetition count', 'Use combined requests'],
|
||
|
'SNMPv3' => ['SNMP version', 'Max repetition count', 'Context name', 'Security name', 'Security level', 'Use combined requests'],
|
||
|
'authNoPriv' => ['SNMP version', 'Max repetition count', 'Context name', 'Security name', 'Security level',
|
||
|
'Authentication protocol', 'Authentication passphrase', 'Use combined requests'
|
||
|
]
|
||
|
];
|
||
|
|
||
|
// The SNMP interface has specific fields depending on the SNMP version and protocol.
|
||
|
foreach ($data as $field => $labels) {
|
||
|
$select = ($field === 'authNoPriv') ? 'Security level' : 'SNMP version';
|
||
|
$snmp_form->fill([$select => $field]);
|
||
|
$this->assertEquals($labels, array_values($snmp_form->getLabels()
|
||
|
->filter(new CElementFilter(CElementFilter::VISIBLE))->asText())
|
||
|
);
|
||
|
$this->assertFalse($snmp_form->query('xpath:.//label[text()="Use combined requests"]')->one()
|
||
|
->asCheckbox()->isChecked()
|
||
|
);
|
||
|
if ($field === 'SNMPv3') {
|
||
|
// Check fields' lengths.
|
||
|
$field_lenghts = [
|
||
|
'Max repetition count' => 20,
|
||
|
'Context name' => 255,
|
||
|
'Security name' => 64,
|
||
|
'Authentication passphrase' => 64,
|
||
|
'Privacy passphrase' => 64
|
||
|
];
|
||
|
|
||
|
foreach ($field_lenghts as $label => $length) {
|
||
|
$this->assertEquals($length, $snmp_form->getField($label)->getAttribute('maxlength'));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Check hintbox.
|
||
|
$form->query('class:zi-help-filled-small')->one()->waitUntilClickable()->click();
|
||
|
$hint = $this->query('xpath:.//div[@data-hintboxid]')->waitUntilPresent();
|
||
|
|
||
|
// Assert text.
|
||
|
$this->assertEquals('Max repetition count is applicable to discovery and walk only.', $hint->one()->getText());
|
||
|
|
||
|
// Close the hintbox.
|
||
|
$hint->one()->query('xpath:.//button[@class="btn-overlay-close"]')->one()->click();
|
||
|
$hint->waitUntilNotPresent();
|
||
|
|
||
|
// Close host form popup to avoid unexpected alert in further cases.
|
||
|
if (!$this->standalone) {
|
||
|
COverlayDialogElement::find()->one()->close();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static function getCreateData() {
|
||
|
return [
|
||
|
// #0 Host form without mandatory values.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'error' => ['Field "groups" is mandatory.', 'Incorrect value for field "host": cannot be empty.']
|
||
|
]
|
||
|
],
|
||
|
// #1.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'error' => 'Incorrect value for field "host": cannot be empty.'
|
||
|
]
|
||
|
],
|
||
|
// #2.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Empty host group'
|
||
|
],
|
||
|
'error' => 'Field "groups" is mandatory.'
|
||
|
]
|
||
|
],
|
||
|
// #3 Existing host name and visible name.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Available host',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'Host with the same name "Available host" already exists.'
|
||
|
]
|
||
|
],
|
||
|
// #4.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Empty template',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'Template with the same name "Empty template" already exists.'
|
||
|
]
|
||
|
],
|
||
|
// #5.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Existen visible name',
|
||
|
'Host groups' => 'Zabbix servers',
|
||
|
'Visible name' => 'ЗАББИКС Сервер'
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'Host with the same visible name "ЗАББИКС Сервер" already exists.'
|
||
|
]
|
||
|
],
|
||
|
// #6 Host name field validation.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => '@#$%^&*()_+',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'Incorrect characters used for host name "@#$%^&*()_+".'
|
||
|
]
|
||
|
],
|
||
|
// #7 UTF8MB4 check.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host groups' => 'Zabbix servers',
|
||
|
'Host name' => '😀'
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'Incorrect characters used for host name "😀".'
|
||
|
]
|
||
|
],
|
||
|
// #8 Interface fields validation.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Empty ip address',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent',
|
||
|
'ip' => ''
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'IP and DNS cannot be empty for host interface.'
|
||
|
]
|
||
|
],
|
||
|
// #9.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Empty dns',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent',
|
||
|
'ip' => '',
|
||
|
'Connect to' => 'DNS'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'IP and DNS cannot be empty for host interface.'
|
||
|
]
|
||
|
],
|
||
|
// 10.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Empty IP and filled in DNS',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent',
|
||
|
'ip' => '',
|
||
|
'dns' => 'test'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'Interface with DNS "test" cannot have empty IP address.'
|
||
|
]
|
||
|
],
|
||
|
// 11.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Empty dns and filled in IP',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent',
|
||
|
'Connect to' => 'DNS'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'Interface with IP "127.0.0.1" cannot have empty DNS name while having'.
|
||
|
' "Use DNS" property on "Empty dns and filled in IP".'
|
||
|
]
|
||
|
],
|
||
|
// 12.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Empty port',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent',
|
||
|
'port' => ''
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'Port cannot be empty for host interface.'
|
||
|
]
|
||
|
],
|
||
|
// #13 IP validation.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Invalid ip',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent',
|
||
|
'ip' => 'test'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'Invalid IP address "test".'
|
||
|
]
|
||
|
],
|
||
|
// #14.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Invalid ip',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent',
|
||
|
'ip' => '127.0.0.'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'Invalid IP address "127.0.0.".'
|
||
|
]
|
||
|
],
|
||
|
// #15 Port validation.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Invalid port',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'SNMP',
|
||
|
'port' => '100500'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'Incorrect interface port "100500" provided.'
|
||
|
]
|
||
|
],
|
||
|
// #16.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Invalid port',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'IPMI',
|
||
|
'port' => 'test'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'Incorrect interface port "test" provided.'
|
||
|
]
|
||
|
],
|
||
|
// #17.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Invalid port',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'JMX',
|
||
|
'port' => '10.5'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'Incorrect interface port "10.5" provided.'
|
||
|
]
|
||
|
],
|
||
|
// #18 Empty SNMP community.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Invalid snmp community',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'SNMP',
|
||
|
'SNMP community' => ''
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'Incorrect arguments passed to function.'
|
||
|
]
|
||
|
],
|
||
|
// #19 Zero in SNMP Max repetition count.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Invalid snmp community',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'SNMP',
|
||
|
'Max repetition count' => '0'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot add host',
|
||
|
'error' => 'Incorrect arguments passed to function.'
|
||
|
]
|
||
|
],
|
||
|
// #20 Host without interface.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_GOOD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Host without interfaces',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// #21 UTF8MB4 check.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_GOOD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Host with utf8mb4 visible name',
|
||
|
'Host groups' => 'Zabbix servers',
|
||
|
'Visible name' => '😀',
|
||
|
'Description' => '😀🙃😀'
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// #22 Default values of all interfaces.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_GOOD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Host with default values of all interfaces',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'SNMP'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'JMX'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'IPMI'
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// #23 Change default host interface.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_GOOD,
|
||
|
'default_values' => true,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Host with default second agent interface',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent',
|
||
|
'ip' => '127.1.1.1',
|
||
|
'port' => '111'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent',
|
||
|
'ip' => '127.2.2.2',
|
||
|
'port' => '222',
|
||
|
'Default' => true
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// #24 Different versions of SNMP interface and encryption.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_GOOD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Host with different versions of SNMP interface',
|
||
|
'Host groups' => 'Zabbix servers'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'SNMP',
|
||
|
'SNMP version' => 'SNMPv1',
|
||
|
'SNMP community' => 'test'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'SNMP',
|
||
|
'SNMP version' => 'SNMPv2',
|
||
|
'SNMP community' => '{$SNMP_TEST}',
|
||
|
'Max repetition count' => '20'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'SNMP',
|
||
|
'SNMP version' => 'SNMPv3',
|
||
|
'Security level' => 'authPriv',
|
||
|
'Authentication protocol' => 'SHA224'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'SNMP',
|
||
|
'SNMP version' => 'SNMPv3',
|
||
|
'Security level' => 'authPriv',
|
||
|
'Authentication protocol' => 'SHA256',
|
||
|
'Privacy protocol' => 'AES192'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'SNMP',
|
||
|
'SNMP version' => 'SNMPv3',
|
||
|
'Security level' => 'authPriv',
|
||
|
'Authentication protocol' => 'SHA384',
|
||
|
'Privacy protocol' => 'AES192C'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'SNMP',
|
||
|
'SNMP version' => 'SNMPv3',
|
||
|
'Security level' => 'authPriv',
|
||
|
'Authentication protocol' => 'SHA512',
|
||
|
'Privacy protocol' => 'AES256C'
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// #25 All interfaces and all fields in form.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_GOOD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Host with all interfaces',
|
||
|
'Visible name' => 'Host with all interfaces visible name',
|
||
|
'Host groups' => 'Zabbix servers',
|
||
|
'Description' => 'Added description for host with all interfaces',
|
||
|
'Monitored by proxy' => 'Proxy for Discovery rule',
|
||
|
'Enabled' => false
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent',
|
||
|
'ip' => '::1',
|
||
|
'dns' => '1211',
|
||
|
'Connect to' => 'DNS',
|
||
|
'port' => '100'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'SNMP',
|
||
|
'ip' => '',
|
||
|
'dns' => 'localhost',
|
||
|
'Connect to' => 'DNS',
|
||
|
'port' => '200',
|
||
|
'SNMP version' => 'SNMPv3',
|
||
|
'Max repetition count' => '15',
|
||
|
'Context name' => 'aaa',
|
||
|
'Security name' => 'bbb',
|
||
|
'Security level' => 'authPriv',
|
||
|
'Authentication protocol' => 'SHA1',
|
||
|
'Authentication passphrase' => 'ccc',
|
||
|
'Privacy protocol' => 'AES128',
|
||
|
'Privacy passphrase' => 'ddd',
|
||
|
'Use combined requests' => false
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'SNMP',
|
||
|
'ip' => '0:0:0:0:0:ffff:7c01:101',
|
||
|
'dns' => 'test',
|
||
|
'port' => '500',
|
||
|
'SNMP version' => 'SNMPv1',
|
||
|
'SNMP community' => 'test',
|
||
|
'Use combined requests' => true
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'JMX',
|
||
|
'dns' => '1333',
|
||
|
'Connect to' => 'DNS',
|
||
|
'port' => '300'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'IPMI',
|
||
|
'ip' => '127.2.2.2',
|
||
|
'dns' => '1444',
|
||
|
'port' => '400'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'IPMI',
|
||
|
'ip' => '127.3.3.3',
|
||
|
'dns' => '1444',
|
||
|
'Connect to' => 'DNS',
|
||
|
'port' => '500',
|
||
|
'Default' => true
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test for checking new host creation form.
|
||
|
*
|
||
|
* @param array $data data provider
|
||
|
*/
|
||
|
public function checkHostCreate($data) {
|
||
|
if ($data['expected'] === TEST_BAD) {
|
||
|
$old_hash = CDBHelper::getHash($this->hosts_sql);
|
||
|
$interface_old_hash = CDBHelper::getHash($this->interface_snmp_sql);
|
||
|
}
|
||
|
|
||
|
$this->page->login()->open($this->link)->waitUntilReady();
|
||
|
|
||
|
if ($this->standalone) {
|
||
|
$form = $this->query('id:host-form')->asForm()->waitUntilReady()->one();
|
||
|
}
|
||
|
else {
|
||
|
$this->query('button:Create host')->one()->waitUntilClickable()->click();
|
||
|
$form = COverlayDialogElement::find()->asForm()->one()->waitUntilReady();
|
||
|
}
|
||
|
|
||
|
$form->fill(CTestArrayHelper::get($data, 'host_fields', []));
|
||
|
|
||
|
// Set name for field "Default".
|
||
|
$names = ['1' => 'default'];
|
||
|
$interfaces_form = $form->getFieldContainer('Interfaces')->asHostInterfaceElement(['names' => $names]);
|
||
|
$interfaces = CTestArrayHelper::get($data, 'interfaces', []);
|
||
|
$interfaces_form->fill($interfaces);
|
||
|
$form->submit();
|
||
|
|
||
|
switch ($data['expected']) {
|
||
|
case TEST_GOOD:
|
||
|
$this->assertMessage(TEST_GOOD, 'Host added');
|
||
|
$this->page->assertTitle($this->monitoring ? 'Hosts' : 'Configuration of hosts');
|
||
|
|
||
|
// Check host fields.
|
||
|
$host = CTestArrayHelper::get($data, 'host_fields.Visible name', $data['host_fields']['Host name']);
|
||
|
|
||
|
$form = $this->filterAndSelectHost($host);
|
||
|
$form->checkValue($data['host_fields']);
|
||
|
|
||
|
foreach ($interfaces as &$interface) {
|
||
|
$interface['action'] = CTestArrayHelper::get($interface, 'action', USER_ACTION_ADD);
|
||
|
|
||
|
// Add default values for interface, if it added without any values except action and type.
|
||
|
if (count($interface) === 2 && $interface['action'] === USER_ACTION_ADD) {
|
||
|
$interface = $this->default_values[$interface['type']];
|
||
|
}
|
||
|
|
||
|
unset($interface['index'], $interface['action'], $interface['type']);
|
||
|
}
|
||
|
unset($interface);
|
||
|
|
||
|
$data['interfaces'] = $interfaces;
|
||
|
|
||
|
// Check host fields in DB.
|
||
|
$this->assertDatabaseFields($data);
|
||
|
|
||
|
// Check interfaces field values.
|
||
|
$form->getFieldContainer('Interfaces')->asHostInterfaceElement(['names' => $names])
|
||
|
->checkValue($data['interfaces']);
|
||
|
|
||
|
COverlayDialogElement::find()->one()->close();
|
||
|
break;
|
||
|
|
||
|
case TEST_BAD:
|
||
|
$this->assertEquals($old_hash, CDBHelper::getHash($this->hosts_sql));
|
||
|
$this->assertEquals($interface_old_hash, CDBHelper::getHash($this->interface_snmp_sql));
|
||
|
$this->assertMessage(TEST_BAD, CTestArrayHelper::get($data, 'error_title', 'Cannot add host'), $data['error']);
|
||
|
|
||
|
if (!$this->standalone) {
|
||
|
COverlayDialogElement::find()->one()->close();
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static function getValidationUpdateData() {
|
||
|
return [
|
||
|
// Host form validation.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => '',
|
||
|
'Host groups' => ''
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_REMOVE,
|
||
|
'index' => 0
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_REMOVE,
|
||
|
'index' => 0
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_REMOVE,
|
||
|
'index' => 0
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_REMOVE,
|
||
|
'index' => 0
|
||
|
]
|
||
|
],
|
||
|
'error' => ['Field "groups" is mandatory.', 'Incorrect value for field "host": cannot be empty.'
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => '',
|
||
|
'Host groups' => ''
|
||
|
],
|
||
|
'error' => ['Field "groups" is mandatory.', 'Incorrect value for field "host": cannot be empty.']
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => ''
|
||
|
],
|
||
|
'error' => 'Incorrect value for field "host": cannot be empty.'
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Empty host group',
|
||
|
'Host groups' => ''
|
||
|
],
|
||
|
'error' => 'Field "groups" is mandatory.'
|
||
|
]
|
||
|
],
|
||
|
// Existing host name and visible name.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Available host'
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'Host with the same name "Available host" already exists.'
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Empty template'
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'Template with the same name "Empty template" already exists.'
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Visible name' => 'ЗАББИКС Сервер'
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'Host with the same visible name "ЗАББИКС Сервер" already exists.'
|
||
|
]
|
||
|
],
|
||
|
// Host name field validation.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => '@#$%^&*()_+'
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'Incorrect characters used for host name "@#$%^&*()_+".'
|
||
|
]
|
||
|
],
|
||
|
// UTF8MB4 check.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => '😀'
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'Incorrect characters used for host name "😀".'
|
||
|
]
|
||
|
],
|
||
|
// Interface fields validation.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 0,
|
||
|
'ip' => ''
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'IP and DNS cannot be empty for host interface.'
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Empty dns'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 0,
|
||
|
'ip' => '',
|
||
|
'Connect to' => 'DNS'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'IP and DNS cannot be empty for host interface.'
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Empty IP and filled in DNS'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 0,
|
||
|
'ip' => '',
|
||
|
'dns' => 'test'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'Interface with DNS "test" cannot have empty IP address.'
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Empty dns and filled in IP'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 0,
|
||
|
'Connect to' => 'DNS'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'Interface with IP "127.1.1.1" cannot have empty DNS name while having'.
|
||
|
' "Use DNS" property on "Empty dns and filled in IP".'
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Empty port'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 0,
|
||
|
'port' => ''
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'Port cannot be empty for host interface.'
|
||
|
]
|
||
|
],
|
||
|
// IP validation.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Invalid ip'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 0,
|
||
|
'ip' => 'test'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'Invalid IP address "test".'
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Invalid ip'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 0,
|
||
|
'ip' => '127.0.0.'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'Invalid IP address "127.0.0.".'
|
||
|
]
|
||
|
],
|
||
|
// Port validation.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Invalid port'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 0,
|
||
|
'port' => '100500'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'Incorrect interface port "100500" provided.'
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Invalid port'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 0,
|
||
|
'port' => 'test'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'Incorrect interface port "test" provided.'
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Invalid port'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 0,
|
||
|
'port' => '10.5'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'Incorrect interface port "10.5" provided.'
|
||
|
]
|
||
|
],
|
||
|
// Empty SNMP community.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Invalid snmp community'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 1,
|
||
|
'SNMP community' => ''
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'Incorrect arguments passed to function.'
|
||
|
]
|
||
|
],
|
||
|
// Zero Max repetition count.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Invalid max repetition count'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 1,
|
||
|
'SNMP version' => 'SNMPv2',
|
||
|
'SNMP community' => '{$SNMP_COMMUNITY}',
|
||
|
'Max repetition count' => '0'
|
||
|
]
|
||
|
],
|
||
|
'error_title' => 'Cannot update host',
|
||
|
'error' => 'Incorrect arguments passed to function.'
|
||
|
]
|
||
|
]
|
||
|
];
|
||
|
}
|
||
|
|
||
|
public static function getUpdateData() {
|
||
|
return [
|
||
|
// Successful host form update.
|
||
|
// Add default interface values.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_GOOD,
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'SNMP'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'JMX'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'IPMI'
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Set "Default" option to another interface.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_GOOD,
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent',
|
||
|
'ip' => '',
|
||
|
'dns' => 'agent',
|
||
|
'Connect to' => 'DNS',
|
||
|
'port' => '10054',
|
||
|
'Default' => true
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'SNMP',
|
||
|
'ip' => '',
|
||
|
'dns' => 'snmp',
|
||
|
'Connect to' => 'DNS',
|
||
|
'port' => '166',
|
||
|
'SNMP version' => 'SNMPv3',
|
||
|
'Max repetition count' => '10',
|
||
|
'Context name' => 'zabbix',
|
||
|
'Security name' => 'selenium',
|
||
|
'Security level' => 'authPriv',
|
||
|
'Authentication protocol' => 'SHA1',
|
||
|
'Authentication passphrase' => 'test123',
|
||
|
'Privacy protocol' => 'AES128',
|
||
|
'Privacy passphrase' => '456test',
|
||
|
'Default' => true
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'IPMI',
|
||
|
'ip' => '',
|
||
|
'dns' => 'ipmi',
|
||
|
'Connect to' => 'DNS',
|
||
|
'port' => '500',
|
||
|
'Default' => true
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Remove all interfaces except JMX.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_GOOD,
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_REMOVE,
|
||
|
'index' => 0
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_REMOVE,
|
||
|
'index' => 0
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_REMOVE,
|
||
|
'index' => 1
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Update all fields.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_GOOD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Update host with all interfaces',
|
||
|
'Visible name' => 'Update host with all interfaces visible name',
|
||
|
'Host groups' => 'Linux servers',
|
||
|
'Description' => 'Update description',
|
||
|
'Monitored by proxy' => 'Active proxy 3',
|
||
|
'Enabled' => false
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 0,
|
||
|
'ip' => '',
|
||
|
'dns' => 'zabbix.com',
|
||
|
'Connect to' => 'DNS'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 1,
|
||
|
'ip' => '',
|
||
|
'dns' => 'zabbix.com',
|
||
|
'port' => '122',
|
||
|
'Connect to' => 'DNS',
|
||
|
'SNMP version' => 'SNMPv3',
|
||
|
'Max repetition count' => '90',
|
||
|
'Context name' => 'new-zabbix',
|
||
|
'Security name' => 'new-selenium',
|
||
|
'Security level' => 'authNoPriv',
|
||
|
'Authentication protocol' => 'SHA384',
|
||
|
'Authentication passphrase' => 'new-test123',
|
||
|
'Use combined requests' => true
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 2,
|
||
|
'ip' => '',
|
||
|
'dns' => 'zabbix.com',
|
||
|
'Connect to' => 'DNS'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 3,
|
||
|
'ip' => '',
|
||
|
'dns' => 'zabbix.com',
|
||
|
'Connect to' => 'DNS'
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// UTF8MB4 check.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_GOOD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Update host with utf8 visible name',
|
||
|
'Host groups' => 'Linux servers',
|
||
|
'Visible name' => '😀😀',
|
||
|
'Description' => '😀😀😀😀😀😀😀'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_REMOVE,
|
||
|
'index' => 1
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_REMOVE,
|
||
|
'index' => 1
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Add two agent interfaces and remove it.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_GOOD,
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_REMOVE,
|
||
|
'index' => 1
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_REMOVE,
|
||
|
'index' => 1
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
// Mixed actions Add, Remove, Update interfaces.
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_GOOD,
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'Mixed interface actions',
|
||
|
'Visible name' => '',
|
||
|
'Host groups' => 'Discovered hosts',
|
||
|
'Description' => '',
|
||
|
'Monitored by proxy' => '(no proxy)'
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'Agent'
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_REMOVE,
|
||
|
'index' => 3
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_UPDATE,
|
||
|
'index' => 2,
|
||
|
'port' => '501',
|
||
|
'SNMP version' => 'SNMPv3',
|
||
|
'Max repetition count' => '20',
|
||
|
'Context name' => 'new-zabbix',
|
||
|
'Security name' => 'new-selenium',
|
||
|
'Security level' => 'noAuthNoPriv',
|
||
|
'Use combined requests' => true
|
||
|
],
|
||
|
[
|
||
|
'action' => USER_ACTION_REMOVE,
|
||
|
'index' => 3
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test for checking existing host update form.
|
||
|
*
|
||
|
* @param array $data data provider
|
||
|
*/
|
||
|
public function checkHostUpdate($data) {
|
||
|
if ($data['expected'] === TEST_BAD) {
|
||
|
$host_old_hash = CDBHelper::getHash($this->hosts_sql);
|
||
|
$interface_old_hash = CDBHelper::getHash($this->interface_snmp_sql);
|
||
|
}
|
||
|
|
||
|
$source = [
|
||
|
'host_fields' => [
|
||
|
'Host name' => 'testFormHost_Update',
|
||
|
'Visible name' => 'testFormHost_Update Visible name',
|
||
|
'Host groups' => 'Zabbix servers',
|
||
|
'Description' => 'Created host via API to test update functionality in host form and interfaces',
|
||
|
'Monitored by proxy' => 'Proxy for Discovery rule',
|
||
|
'Enabled' => true
|
||
|
],
|
||
|
'interfaces' => [
|
||
|
'Agent' => [
|
||
|
[
|
||
|
'type' => 'Agent',
|
||
|
'ip' => '127.1.1.1',
|
||
|
'dns' => '',
|
||
|
'Connect to' => 'IP',
|
||
|
'port' => '10011'
|
||
|
]
|
||
|
],
|
||
|
'SNMP' => [
|
||
|
[
|
||
|
'ip' => '127.2.2.2',
|
||
|
'dns' => '',
|
||
|
'Connect to' => 'IP',
|
||
|
'port' => '122',
|
||
|
'SNMP version' => 'SNMPv1',
|
||
|
'SNMP community' => '🙃zabbix🙃',
|
||
|
'Use combined requests' => false
|
||
|
]
|
||
|
],
|
||
|
'JMX' => [
|
||
|
[
|
||
|
'type' => 'JMX',
|
||
|
'ip' => '127.4.4.4',
|
||
|
'dns' => '',
|
||
|
'Connect to' => 'IP',
|
||
|
'port' => '426'
|
||
|
]
|
||
|
],
|
||
|
'IPMI' => [
|
||
|
[
|
||
|
'type' => 'JMX',
|
||
|
'ip' => '',
|
||
|
'dns' => 'selenium.test',
|
||
|
'Connect to' => 'DNS',
|
||
|
'port' => '30053'
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
];
|
||
|
|
||
|
$host = 'testFormHost_Update Visible name';
|
||
|
$hostid = CDBHelper::getValue('SELECT hostid FROM hosts WHERE name='.zbx_dbstr($host));
|
||
|
|
||
|
$form = $this->openForm(($this->standalone ? $this->link.$hostid : $this->link), $host);
|
||
|
$form->fill(CTestArrayHelper::get($data, 'host_fields', []));
|
||
|
|
||
|
// Set name for field "Default".
|
||
|
$names = ['1' => 'default'];
|
||
|
$interfaces_form = $form->getFieldContainer('Interfaces')->asHostInterfaceElement(['names' => $names]);
|
||
|
$interfaces_form->fill(CTestArrayHelper::get($data, 'interfaces', []));
|
||
|
$form->submit();
|
||
|
$this->page->WaitUntilReady();
|
||
|
|
||
|
switch ($data['expected']) {
|
||
|
case TEST_GOOD:
|
||
|
$this->assertMessage(TEST_GOOD, 'Host updated');
|
||
|
|
||
|
$host = (CTestArrayHelper::get($data, 'host_fields.Visible name') === "")
|
||
|
? CTestArrayHelper::get($data, 'host_fields.Host name', 'testFormHost_Update')
|
||
|
: CTestArrayHelper::get($data, 'host_fields.Visible name', 'testFormHost_Update Visible name');
|
||
|
|
||
|
$form = $this->filterAndSelectHost($host);
|
||
|
|
||
|
// Update or add new source data from host data.
|
||
|
foreach (CTestArrayHelper::get($data, 'host_fields', []) as $key => $value) {
|
||
|
$source['host_fields'][$key] = $value;
|
||
|
}
|
||
|
|
||
|
// Check host fields.
|
||
|
$form->checkValue($source['host_fields']);
|
||
|
|
||
|
// Preparing reference data for interfaces.
|
||
|
foreach ($data['interfaces'] as $i => $interface) {
|
||
|
$interface['action'] = CTestArrayHelper::get($interface, 'action', USER_ACTION_ADD);
|
||
|
|
||
|
switch ($interface['action']) {
|
||
|
case USER_ACTION_ADD:
|
||
|
$type = CTestArrayHelper::get($interface, 'type', 'Agent');
|
||
|
// Add default values for interface, if it added without any values, except action and type.
|
||
|
if (count($interface) === 2) {
|
||
|
$interface = $this->default_values[$interface['type']];
|
||
|
$interface['type'] = $type;
|
||
|
}
|
||
|
|
||
|
$source['interfaces'][$type][] = $interface;
|
||
|
break;
|
||
|
|
||
|
case USER_ACTION_REMOVE:
|
||
|
foreach (array_keys($source['interfaces']) as $type) {
|
||
|
$count = count($source['interfaces'][$type]);
|
||
|
if ($interface['index'] >= $count) {
|
||
|
$interface['index'] -= $count;
|
||
|
}
|
||
|
else {
|
||
|
unset($source['interfaces'][$type][$interface['index']]);
|
||
|
// Reindex the keys to start from 0.
|
||
|
$source['interfaces'][$type] = array_values($source['interfaces'][$type]);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case USER_ACTION_UPDATE:
|
||
|
foreach (array_keys($source['interfaces']) as $type) {
|
||
|
$count = count($source['interfaces'][$type]);
|
||
|
if ($interface['index'] >= $count) {
|
||
|
$interface['index'] -= $count;
|
||
|
}
|
||
|
else {
|
||
|
// Update or add new source interface fields from host data.
|
||
|
foreach ($interface as $key => $value) {
|
||
|
$source['interfaces'][$type][$interface['index']][$key] = $value;
|
||
|
}
|
||
|
|
||
|
if (CTestArrayHelper::get($interface, 'SNMP version', false) === 'SNMPv3') {
|
||
|
// 'SNMP community' used only by SNMPv1 and SNMPv2 interfaces.
|
||
|
unset($source['interfaces']['SNMP'][0]['SNMP community']);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Remove interface type as array key in source data.
|
||
|
$source['interfaces'] = array_merge($source['interfaces']['Agent'], $source['interfaces']['SNMP'],
|
||
|
$source['interfaces']['JMX'], $source['interfaces']['IPMI']);
|
||
|
|
||
|
// Remove unnecessary keys from source array to check the values on frontend.
|
||
|
foreach ($source['interfaces'] as &$interface) {
|
||
|
unset($interface['index'], $interface['action'], $interface['type']);
|
||
|
}
|
||
|
unset($interface);
|
||
|
|
||
|
// Check host fields in DB.
|
||
|
$this->assertDatabaseFields($source);
|
||
|
|
||
|
// Check interfaces field values.
|
||
|
$form->getFieldContainer('Interfaces')->asHostInterfaceElement(['names' => $names])
|
||
|
->checkValue($source['interfaces']);
|
||
|
|
||
|
COverlayDialogElement::find()->one()->close();
|
||
|
break;
|
||
|
|
||
|
case TEST_BAD:
|
||
|
$this->assertEquals($host_old_hash, CDBHelper::getHash($this->hosts_sql));
|
||
|
$this->assertEquals($interface_old_hash, CDBHelper::getHash($this->interface_snmp_sql));
|
||
|
|
||
|
$error_title = CTestArrayHelper::get($data, 'error_title', 'Cannot update host');
|
||
|
$this->assertMessage(TEST_BAD, $error_title, $data['error']);
|
||
|
|
||
|
if (!$this->standalone) {
|
||
|
COverlayDialogElement::find()->one()->close();
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Update the host without any changes and check host and interfaces hashes.
|
||
|
*/
|
||
|
public function checkHostSimpleUpdate() {
|
||
|
$host_old_hash = CDBHelper::getHash($this->hosts_sql);
|
||
|
$interface_old_hash = CDBHelper::getHash($this->interface_snmp_sql);
|
||
|
|
||
|
$host = 'testFormHost_Update';
|
||
|
$visible_name = 'testFormHost_Update Visible name';
|
||
|
$hostid = CDBHelper::getValue('SELECT hostid FROM hosts WHERE host='.zbx_dbstr($host));
|
||
|
|
||
|
$form = $this->openForm(($this->standalone ? $this->link.$hostid : $this->link), $visible_name);
|
||
|
$this->page->waitUntilReady();
|
||
|
$form->submit();
|
||
|
$this->assertMessage(TEST_GOOD, 'Host updated');
|
||
|
|
||
|
$this->assertEquals($host_old_hash, CDBHelper::getHash($this->hosts_sql));
|
||
|
$this->assertEquals($interface_old_hash, CDBHelper::getHash($this->interface_snmp_sql));
|
||
|
}
|
||
|
|
||
|
public static function getCloneData() {
|
||
|
return [
|
||
|
[
|
||
|
[
|
||
|
'host' => 'testFormHost with secret Macro',
|
||
|
'items' => 0,
|
||
|
'fields' => [
|
||
|
'Host name' => microtime().' clone with secret Macros'
|
||
|
],
|
||
|
'expected' => TEST_ERROR,
|
||
|
'error' => 'The cloned host contains user defined macros with type "Secret text".'.
|
||
|
' The value and type of these macros were reset.'
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'host' => 'testFormHost with items',
|
||
|
'items' => 3,
|
||
|
'fields' => [
|
||
|
'Host name' => microtime().' clone without interface changes'
|
||
|
]
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'host' => 'testFormHost with items',
|
||
|
'items' => 3,
|
||
|
'fields' => [
|
||
|
'Host name' => microtime().' clone with interface changes',
|
||
|
'Visible name' => microtime().'😀😀😀',
|
||
|
'Description' => '😀😀😀😀😀😀😀',
|
||
|
'Interfaces' => [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'SNMP',
|
||
|
'ip' => '127.3.3.3',
|
||
|
'dns' => '',
|
||
|
'Connect to' => 'IP',
|
||
|
'port' => '122',
|
||
|
'SNMP version' => 'SNMPv3',
|
||
|
'Max repetition count' => '13',
|
||
|
'Context name' => 'zabbix',
|
||
|
'Security name' => 'selenium',
|
||
|
'Security level' => 'authPriv',
|
||
|
'Authentication protocol' => 'SHA256',
|
||
|
'Authentication passphrase' => 'test123',
|
||
|
'Privacy protocol' => 'AES256',
|
||
|
'Privacy passphrase' => '456test',
|
||
|
'Use combined requests' => false
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
]
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Clone a host and compare the data with the original host.
|
||
|
*
|
||
|
* @param array $data data provider with fields values
|
||
|
*/
|
||
|
public function cloneHost($data) {
|
||
|
$hostid = CDBHelper::getValue('SELECT hostid FROM hosts WHERE host='.zbx_dbstr($data['host']));
|
||
|
$form = $this->openForm(($this->standalone ? 'zabbix.php?action=host.edit&hostid='.$hostid : $this->link), $data['host']);
|
||
|
|
||
|
// Get values from form.
|
||
|
$form->fill($data['fields']);
|
||
|
$original = $form->getFields()->filter(new CElementFilter(CElementFilter::VISIBLE))->asValues();
|
||
|
|
||
|
// Clone host.
|
||
|
$this->query('button', 'Clone')->waitUntilClickable()->one()->click();
|
||
|
|
||
|
$cloned_form = (!$this->standalone)
|
||
|
? COverlayDialogElement::find()->asForm()->waitUntilReady()->one()
|
||
|
: $this->query('id:host-form')->asForm()->waitUntilVisible()->one();
|
||
|
|
||
|
if (CTestArrayHelper::get($data, 'expected')) {
|
||
|
$this->assertMessage(TEST_ERROR, null, $data['error']);
|
||
|
CMessageElement::find()->one()->close();
|
||
|
}
|
||
|
|
||
|
$cloned_form->submit();
|
||
|
$this->page->waitUntilReady();
|
||
|
$this->assertMessage(TEST_GOOD, 'Host added');
|
||
|
|
||
|
// Check the values of the original host with the cloned host.
|
||
|
$this->filterAndSelectHost((CTestArrayHelper::get($data['fields'], 'Visible name', $data['fields']['Host name'])))
|
||
|
->checkValue($original);
|
||
|
COverlayDialogElement::find()->one()->close();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check host fields data with data in DB.
|
||
|
*
|
||
|
* @param array $data data provider with fields values
|
||
|
*/
|
||
|
private function assertDatabaseFields($data) {
|
||
|
$db_default = [
|
||
|
'name' => $data['host_fields']['Host name'],
|
||
|
'description' => '',
|
||
|
'status' => 0
|
||
|
];
|
||
|
$db_host = CDBHelper::getRow('SELECT hostid, host, name, description, status FROM hosts WHERE host='.
|
||
|
zbx_dbstr($data['host_fields']['Host name'])
|
||
|
);
|
||
|
|
||
|
if (CTestArrayHelper::get($data, 'host_fields.Visible name') === "") {
|
||
|
$data['host_fields']['Visible name'] = $data['host_fields']['Host name'];
|
||
|
}
|
||
|
|
||
|
$fields = ['Host name' => 'host', 'Visible name' => 'name', 'Description' => 'description', 'Enabled' => 'status'];
|
||
|
foreach ($fields as $ui_field => $db_field) {
|
||
|
if (array_key_exists($ui_field, $data['host_fields'])) {
|
||
|
if ($ui_field === 'Enabled') {
|
||
|
$data['host_fields'][$ui_field] = ($data['host_fields'][$ui_field] === false)
|
||
|
? HOST_STATUS_NOT_MONITORED
|
||
|
: HOST_STATUS_MONITORED;
|
||
|
}
|
||
|
$this->assertEquals($data['host_fields'][$ui_field], $db_host[$db_field]);
|
||
|
}
|
||
|
else {
|
||
|
$this->assertEquals($db_default[$db_field], $db_host[$db_field]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Check interfaces amount in DB.
|
||
|
$db_interfaces = CDBHelper::getCount('SELECT NULL FROM interface WHERE hostid='.$db_host['hostid']);
|
||
|
$this->assertEquals(count($data['interfaces']), $db_interfaces);
|
||
|
}
|
||
|
|
||
|
public static function getCancelData() {
|
||
|
return [
|
||
|
[
|
||
|
[
|
||
|
'action' => 'Add'
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'action' => 'Update'
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'action' => 'Clone'
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'action' => 'Delete'
|
||
|
]
|
||
|
]
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test for checking host actions cancelling.
|
||
|
*
|
||
|
* @param array $data data provider with fields values
|
||
|
*/
|
||
|
public function checkCancel($data) {
|
||
|
$host_old_hash = CDBHelper::getHash($this->hosts_sql);
|
||
|
$interface_old_hash = CDBHelper::getHash($this->interface_snmp_sql);
|
||
|
|
||
|
$host = 'testFormHost with items';
|
||
|
$hostid = CDBHelper::getValue('SELECT hostid FROM hosts WHERE host='.zbx_dbstr($host));
|
||
|
$new_name = microtime(true).' Cancel '.$host;
|
||
|
|
||
|
$interface = [
|
||
|
[
|
||
|
'action' => USER_ACTION_ADD,
|
||
|
'type' => 'SNMP',
|
||
|
'ip' => '0:0:0:0:0:ffff:7c01:101',
|
||
|
'dns' => 'test',
|
||
|
'port' => '500',
|
||
|
'SNMP version' => 'SNMPv1',
|
||
|
'SNMP community' => 'test',
|
||
|
'Use combined requests' => false
|
||
|
]
|
||
|
];
|
||
|
|
||
|
if ($data['action'] === 'Add') {
|
||
|
$this->page->login()->open($this->link)->waitUntilReady();
|
||
|
|
||
|
if (!$this->standalone) {
|
||
|
$this->query('button:Create host')->one()->waitUntilClickable()->click();
|
||
|
$form = COverlayDialogElement::find()->waitUntilReady()->one()->asForm();
|
||
|
}
|
||
|
else {
|
||
|
$form = $this->query('id:host-form')->asForm()->waitUntilReady()->one();
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
$form = $this->openForm(($this->standalone ? 'zabbix.php?action=host.edit&hostid='.$hostid : $this->link), $host);
|
||
|
}
|
||
|
|
||
|
$form_type = ($this->standalone) ? $form : COverlayDialogElement::find()->waitUntilReady()->one();
|
||
|
|
||
|
// Change the host data to make sure that the changes are not saved to the database after cancellation.
|
||
|
$form->fill(['Host name' => $new_name]);
|
||
|
$interfaces_form = $form->getFieldContainer('Interfaces')->asHostInterfaceElement(['names' => ['1' => 'default']]);
|
||
|
$interfaces_form->fill($interface);
|
||
|
|
||
|
if (in_array($data['action'], ['Clone', 'Delete'])) {
|
||
|
$form_type->query('button', $data['action'])->one()->click();
|
||
|
}
|
||
|
if ($data['action'] === 'Delete') {
|
||
|
$this->page->dismissAlert();
|
||
|
}
|
||
|
|
||
|
$this->page->waitUntilReady();
|
||
|
|
||
|
// Check that the host creation page is open after cloning.
|
||
|
if ($data['action'] === 'Clone') {
|
||
|
$form_type->invalidate();
|
||
|
$id = CDBHelper::getValue('SELECT hostid FROM hosts WHERE host='.zbx_dbstr($host));
|
||
|
$expected_url = PHPUNIT_URL.'zabbix.php?action=host.edit&hostid='.$id.'&clone=1';
|
||
|
|
||
|
$this->assertEquals($expected_url, $this->page->getCurrentUrl());
|
||
|
$this->assertFalse($form_type->query("xpath:.//ul[".CXPathHelper::fromClass('filter-breadcrumb')."]")
|
||
|
->one(false)->isValid()
|
||
|
);
|
||
|
$this->assertFalse($form_type->query('button', ['Update', 'Clone', 'Delete'])->one(false)
|
||
|
->isValid()
|
||
|
);
|
||
|
$this->assertTrue($form_type->query('button', ['Add', 'Cancel'])->one(false)->isValid());
|
||
|
}
|
||
|
|
||
|
$form_type->query('button:Cancel')->waitUntilClickable()->one()->click();
|
||
|
|
||
|
// Check invariability of host data in the database.
|
||
|
$this->assertEquals($host_old_hash, CDBHelper::getHash($this->hosts_sql));
|
||
|
$this->assertEquals($interface_old_hash, CDBHelper::getHash($this->interface_snmp_sql));
|
||
|
$this->assertEquals(0, CDBHelper::getCount('SELECT null FROM hosts WHERE host='.zbx_dbstr($new_name)));
|
||
|
}
|
||
|
|
||
|
public static function getDeleteData() {
|
||
|
return [
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_GOOD,
|
||
|
'name' => 'testFormHost with items'
|
||
|
]
|
||
|
],
|
||
|
[
|
||
|
[
|
||
|
'expected' => TEST_BAD,
|
||
|
'name' => 'Host for suppression',
|
||
|
'error' => 'Cannot delete host "Host for suppression" because maintenance "Maintenance for suppression test"'.
|
||
|
' must contain at least one host or host group.'
|
||
|
]
|
||
|
]
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Test for checking host deleting.
|
||
|
*
|
||
|
* @param array $data data provider with fields values
|
||
|
*/
|
||
|
public function checkDelete($data) {
|
||
|
$hostid = CDBHelper::getValue('SELECT hostid FROM hosts WHERE host='.zbx_dbstr($data['name']));
|
||
|
|
||
|
if ($data['expected'] === TEST_BAD) {
|
||
|
$old_hash = CDBHelper::getHash($this->hosts_sql);
|
||
|
}
|
||
|
else {
|
||
|
// Get snmp interface ids.
|
||
|
$interfaceids = CDBHelper::getAll('SELECT interfaceid FROM interface WHERE hostid='.$hostid.' AND type=2');
|
||
|
$ids = array_column($interfaceids, 'interfaceid');
|
||
|
}
|
||
|
|
||
|
$form = $this->openForm(($this->standalone ? $this->link.$hostid : $this->link), $data['name']);
|
||
|
$form_type = ($this->standalone) ? $form : COverlayDialogElement::find()->waitUntilReady()->one();
|
||
|
$form_type->query('button:Delete')->waitUntilClickable()->one()->click();
|
||
|
$this->page->acceptAlert();
|
||
|
$this->page->waitUntilReady();
|
||
|
|
||
|
switch ($data['expected']) {
|
||
|
case TEST_GOOD:
|
||
|
$this->assertMessage(TEST_GOOD, 'Host deleted');
|
||
|
|
||
|
// Check if all host records have been deleted.
|
||
|
$tables = ['hosts', 'interface', 'items', 'hostmacro', 'hosts_groups', 'hosts_templates',
|
||
|
'maintenances_hosts', 'host_inventory'];
|
||
|
|
||
|
foreach ($tables as $table) {
|
||
|
$this->assertEquals(0, CDBHelper::getCount('SELECT null FROM '.$table.' WHERE hostid='.$hostid));
|
||
|
}
|
||
|
$this->assertEquals(0, CDBHelper::getCount('SELECT null FROM interface_snmp'.
|
||
|
' WHERE interfaceid IN ('.CDBHelper::escape($ids).')')
|
||
|
);
|
||
|
break;
|
||
|
|
||
|
case TEST_BAD:
|
||
|
$this->assertEquals($old_hash, CDBHelper::getHash($this->hosts_sql));
|
||
|
$this->assertMessage(TEST_BAD, 'Cannot delete host', $data['error']);
|
||
|
|
||
|
if (!$this->standalone) {
|
||
|
$form_type->close();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Function for opening host form.
|
||
|
*
|
||
|
* @param string $url url of page where host form is opened
|
||
|
* @param string $host host name to be opened
|
||
|
*/
|
||
|
private function openForm($url, $host) {
|
||
|
$this->page->login()->open($url)->waitUntilReady();
|
||
|
|
||
|
return ($this->standalone)
|
||
|
? $this->query('id:host-form')->asForm()->waitUntilReady()->one()
|
||
|
: $this->filterAndSelectHost($host);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Function for filtering necessary host on page.
|
||
|
*
|
||
|
* @param string $host host name to be filtered
|
||
|
*
|
||
|
* @return CFormElement
|
||
|
*/
|
||
|
public function filterAndSelectHost($host) {
|
||
|
$table = $this->query('xpath://table[@class="list-table"]')->asTable()->one()->waitUntilVisible();
|
||
|
$this->query('button:Reset')->one()->click();
|
||
|
$table->waitUntilReloaded();
|
||
|
$this->query('name:zbx_filter')->asForm()->waitUntilReady()->one()->fill(['Name' => $host]);
|
||
|
$this->query('button:Apply')->one()->waitUntilClickable()->click();
|
||
|
$table->waitUntilReloaded();
|
||
|
|
||
|
$host_link = $table->findRow('Name', $host, true)->getColumn('Name')
|
||
|
->query($this->monitoring ? 'tag:a' : "xpath:.//a[@onclick]")->waitUntilClickable();
|
||
|
|
||
|
if ($this->monitoring) {
|
||
|
$host_link->asPopupButton()->one()->select('Host');
|
||
|
}
|
||
|
else {
|
||
|
$host_link->one()->click();
|
||
|
}
|
||
|
|
||
|
return COverlayDialogElement::find()->asForm()->one()->waitUntilReady();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Function for selecting and counting items on particular host.
|
||
|
*
|
||
|
* @param boolean $host name of host
|
||
|
* @param string $count expected items count
|
||
|
*/
|
||
|
public function assertItemsDBCount($host, $count) {
|
||
|
$sql = 'SELECT null FROM items WHERE hostid IN (SELECT hostid FROM hosts WHERE host='.zbx_dbstr($host).')';
|
||
|
$this->assertEquals($count, CDBHelper::getCount($sql));
|
||
|
}
|
||
|
|
||
|
public function checkDiscoveredHostLayout() {
|
||
|
$form = $this->openForm((
|
||
|
($this->standalone)
|
||
|
? $this->link.CDataHelper::get('DiscoveredHosts.discovered_hostid')
|
||
|
: $this->link
|
||
|
), self::DISCOVERED_HOST
|
||
|
);
|
||
|
$form_type = ($this->standalone) ? $form : COverlayDialogElement::find()->waitUntilReady()->one();
|
||
|
|
||
|
// Check tabs available in the form.
|
||
|
$tabs = ['Host', 'IPMI', 'Tags', 'Macros', 'Inventory', 'Encryption'];
|
||
|
$this->assertEquals($tabs, $form->getTabs());
|
||
|
|
||
|
$discovered_interface_id = CDataHelper::get('DiscoveredHosts.discovered_interfaceid');
|
||
|
|
||
|
foreach ($tabs as $tab) {
|
||
|
$form->selectTab($tab);
|
||
|
|
||
|
switch ($tab) {
|
||
|
case 'Host':
|
||
|
foreach (['Discovered by', 'Host name', 'Templates', 'Host groups', 'Interfaces', 'Description',
|
||
|
'Monitored by proxy', 'Enabled'] as $label) {
|
||
|
$this->assertEquals($label, $form->getLabel($label)->getText());
|
||
|
}
|
||
|
|
||
|
$this->assertEquals('LLD for Discovered host tests', $form->getField('Discovered by')->getText());
|
||
|
|
||
|
// Check fields' editability, maxlength and default values.
|
||
|
$host_fields = [
|
||
|
['name' => 'Host name', 'value' => self::DISCOVERED_HOST, 'maxlength' => 128, 'enabled' => false],
|
||
|
['name' => 'Visible name', 'value' => '', 'maxlength' => 128, 'enabled' => false],
|
||
|
['name' => 'id:add_templates_', 'value' => '', 'enabled' => true],
|
||
|
['name' => 'Host groups', 'value' => ['Group created from host prototype 1',
|
||
|
'Group for discovered host test'], 'enabled' => false],
|
||
|
['name' => 'id:interfaces_'.$discovered_interface_id.'_ip', 'value' => '127.0.0.1',
|
||
|
'maxlength' => 64, 'enabled' => false],
|
||
|
['name' => 'id:interfaces_'.$discovered_interface_id.'_dns', 'value' => '',
|
||
|
'maxlength' => 255, 'enabled' => false],
|
||
|
['name' => 'id:interfaces_'.$discovered_interface_id.'_useip', 'value' => 'IP', 'enabled' => false],
|
||
|
['name' => 'id:interfaces_'.$discovered_interface_id.'_port', 'value' => 10050,
|
||
|
'maxlength' => 64, 'enabled' => false],
|
||
|
['name' => 'id:interface_main_'.$discovered_interface_id , 'value' => $discovered_interface_id,
|
||
|
'enabled' => false],
|
||
|
['name' => 'Description', 'value' => '', 'maxlength' => 65535, 'enabled' => true],
|
||
|
['name' => 'Monitored by proxy', 'value' => '(no proxy)', 'enabled' => false],
|
||
|
['name' => 'Enabled', 'value' => true, 'enabled' => true]
|
||
|
];
|
||
|
|
||
|
foreach ($host_fields as $field) {
|
||
|
$this->assertTrue($form->getField($field['name'])->isEnabled($field['enabled']));
|
||
|
$this->assertEquals($field['value'], $form->getField($field['name'])->getValue());
|
||
|
if (CTestArrayHelper::get($field, 'maxlength')) {
|
||
|
$this->assertEquals($field['maxlength'], $form->getField($field['name'])->getAttribute('maxlength'));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$this->assertEquals(self::DISCOVERED_HOST, $form->getField('Visible name')->getAttribute('placeholder'));
|
||
|
|
||
|
// Check hintbox.
|
||
|
$form->query('class:zi-help-filled-small')->one()->click();
|
||
|
$hint = $this->query('xpath:.//div[@data-hintboxid]')->waitUntilPresent();
|
||
|
$this->assertEquals("Templates linked by host discovery cannot be unlinked.".
|
||
|
"\nUse host prototype configuration form to remove automatically linked templates on upcoming discovery.",
|
||
|
$hint->one()->getText()
|
||
|
);
|
||
|
|
||
|
// Close the hint-box.
|
||
|
$hint->one()->query('xpath:.//button[@class="btn-overlay-close"]')->one()->click();
|
||
|
$hint->waitUntilNotPresent();
|
||
|
|
||
|
$host_templates = [
|
||
|
['Name' => self::TEMPLATE_NAMES[0], 'Action' => 'UnlinkUnlink and clear'],
|
||
|
['Name' => self::TEMPLATE_NAMES[1], 'Action' => 'UnlinkUnlink and clear'],
|
||
|
['Name' => self::TEMPLATE_NAMES[2], 'Action' => 'UnlinkUnlink and clear']
|
||
|
];
|
||
|
$this->assertTableData($host_templates, 'id:linked-templates');
|
||
|
|
||
|
foreach (self::TEMPLATE_NAMES as $template) {
|
||
|
$this->assertTrue( $form->query('link', $template)->one()->isClickable());
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case 'IPMI':
|
||
|
$ipmi_values = [
|
||
|
'Authentication algorithm' => 'Default',
|
||
|
'Privilege level' => 'User',
|
||
|
'Username' => '',
|
||
|
'Password' => ''
|
||
|
];
|
||
|
$form->checkValue($ipmi_values);
|
||
|
|
||
|
foreach (array_keys($ipmi_values) as $label) {
|
||
|
$this->assertFalse($form->getField($label)->isEnabled());
|
||
|
}
|
||
|
|
||
|
foreach (['Username', 'Password'] as $fields) {
|
||
|
$this->assertEquals(255, $form->getField($label)->getAttribute('maxlength'));
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case 'Tags':
|
||
|
$tags_table = $form->query('class:tags-table')->asMultifieldTable()->one()->waitUntilVisible();
|
||
|
|
||
|
$expected_tags = [
|
||
|
[
|
||
|
'tag' => 'action',
|
||
|
'value' => 'update'
|
||
|
],
|
||
|
[
|
||
|
'tag' => 'tag without value',
|
||
|
'value' => ''
|
||
|
],
|
||
|
[
|
||
|
'tag' => 'test',
|
||
|
'value' => 'update'
|
||
|
]
|
||
|
];
|
||
|
$tags_table->checkValue($expected_tags);
|
||
|
|
||
|
$this->assertEquals(['Name', 'Value', ''], $tags_table->getHeadersText());
|
||
|
$tags_table->query('button:Add')->waitUntilClickable()->one()->click();
|
||
|
|
||
|
foreach (['id:tags_2_tag' => 'tag', 'id:tags_2_value' => 'value'] as $field => $placeholder) {
|
||
|
$this->assertEquals($placeholder, $form->getField($field)->getAttribute('placeholder'));
|
||
|
$this->assertEquals(255, $form->getField($field)->getAttribute('maxlength'));
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'Macros':
|
||
|
$radio_switcher = $this->query('id:show_inherited_macros')->asSegmentedRadio()->waitUntilPresent()->one();
|
||
|
$macros_table = $this->query('id:tbl_macros')->asMultifieldTable()->one();
|
||
|
$macros_table->checkValue([['Macro' => '','Value' => '', 'Description' => '']]);
|
||
|
$radio_switcher->select('Inherited and host macros');
|
||
|
$macros_table->waitUntilReloaded();
|
||
|
$this->assertSame(['Macro', 'Effective value', '', '', 'Template value', '', 'Global value (configure)'],
|
||
|
$macros_table->getHeadersText()
|
||
|
);
|
||
|
break;
|
||
|
|
||
|
case 'Inventory':
|
||
|
$this->assertFalse($this->query('id:inventory_mode')->asSegmentedRadio()->waitUntilPresent()->one()->isEnabled());
|
||
|
|
||
|
foreach ($form->query("xpath://div[@id='inventory-tab']//div/label")->all()->asText() as $label) {
|
||
|
$this->assertFalse($form->getField($label)->isEnabled());
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'Encryption':
|
||
|
foreach (['Connections to host', 'id:tls_in_none', 'id:tls_in_psk', 'id:tls_in_cert'] as $field) {
|
||
|
$this->assertFalse($form->getField($field)->isEnabled());
|
||
|
}
|
||
|
|
||
|
$this->assertTrue($form->getField('id:tls_in_none')->isChecked());
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$this->assertEquals(4, $form_type->query('button', ['Update', 'Clone', 'Delete', 'Cancel'])->all()
|
||
|
->filter(new CElementFilter(CElementFilter::CLICKABLE))->count()
|
||
|
);
|
||
|
|
||
|
if (!$this->standalone) {
|
||
|
$form_type->close();
|
||
|
}
|
||
|
}
|
||
|
}
|