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.
2290 lines
74 KiB
2290 lines
74 KiB
<?php
|
|
/*
|
|
** Zabbix
|
|
** Copyright (C) 2001-2023 Zabbix SIA
|
|
**
|
|
** This program is free software; you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation; either version 2 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program; if not, write to the Free Software
|
|
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
**/
|
|
|
|
|
|
require_once __DIR__.'/../include/CAPITest.php';
|
|
|
|
/**
|
|
* @onBefore prepareTestData
|
|
*
|
|
* @onAfter clearData
|
|
*/
|
|
class testConnector extends CAPITest {
|
|
|
|
/**
|
|
* Non-existent ID.
|
|
*/
|
|
private const INVALID_ID = self::INVALID_NUMBER;
|
|
|
|
/**
|
|
* Invalid protocol, data_type, status etc.
|
|
*/
|
|
private const INVALID_NUMBER = 999999;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
private static array $data = [
|
|
'connectorids' => [],
|
|
|
|
// Created connectors during connector.create test (deleted at the end).
|
|
'created' => []
|
|
];
|
|
|
|
/**
|
|
* Prepare data for tests.
|
|
*/
|
|
public function prepareTestData(): void {
|
|
$connectors = [
|
|
'get_custom_defaults' => [
|
|
'name' => 'API test connector.get with custom defaults',
|
|
'url' => 'http://localhost/',
|
|
'description' => 'Custom description'
|
|
],
|
|
'get_data_type_events' => [
|
|
'name' => 'API test connector.get with data type (events)',
|
|
'data_type' => ZBX_CONNECTOR_DATA_TYPE_EVENTS,
|
|
'url' => 'http://localhost/'
|
|
],
|
|
'get_url' => [
|
|
'name' => 'API test connector.get with URL (user macro)',
|
|
'url' => '{$URL}'
|
|
],
|
|
'get_http_proxy' => [
|
|
'name' => 'API test connector.get with HTTP proxy (user macro)',
|
|
'url' => 'http://localhost/',
|
|
'http_proxy' => '{$HTTP_PROXY}'
|
|
],
|
|
'get_authtype_basic' => [
|
|
'name' => 'API test connector.get with authtype (basic), username and password',
|
|
'url' => 'http://localhost/',
|
|
'authtype' => ZBX_HTTP_AUTH_BASIC,
|
|
'username' => 'test',
|
|
'password' => '12345678'
|
|
],
|
|
'get_authtype_bearer' => [
|
|
'name' => 'API test connector.get with authtype (bearer)',
|
|
'url' => 'http://localhost/',
|
|
'authtype' => ZBX_HTTP_AUTH_BEARER,
|
|
'token' => '{$BEARER_TOKEN}'
|
|
],
|
|
'get_status_disabled' => [
|
|
'name' => 'API test connector.get with status (disabled)',
|
|
'url' => 'http://localhost/',
|
|
'status' => ZBX_CONNECTOR_STATUS_DISABLED
|
|
],
|
|
'get_tags' => [
|
|
'name' => 'API test connector.get with two tags',
|
|
'url' => 'http://localhost/',
|
|
'tags' => [
|
|
[
|
|
'tag' => 'abc',
|
|
'operator' => CONDITION_OPERATOR_EQUAL,
|
|
'value' => '123'
|
|
],
|
|
[
|
|
'tag' => 'xyz',
|
|
'operator' => CONDITION_OPERATOR_EXISTS
|
|
]
|
|
]
|
|
],
|
|
'update_custom_defaults' => [
|
|
'name' => 'API test connector.update with custom defaults',
|
|
'url' => 'http://localhost/',
|
|
'ssl_cert_file' => 'ssl_cert_file',
|
|
'ssl_key_file' => 'ssl_key_file',
|
|
'ssl_key_password' => 'ssl_key_password'
|
|
],
|
|
'update_authtype_basic' => [
|
|
'name' => 'API test connector.update with authtype (basic), username and password',
|
|
'url' => 'http://localhost/',
|
|
'authtype' => ZBX_HTTP_AUTH_BASIC,
|
|
'username' => 'test',
|
|
'password' => '12345678'
|
|
],
|
|
'update_tags' => [
|
|
'name' => 'API test connector.update with evaltype (or) and two tags',
|
|
'url' => 'http://localhost/',
|
|
'tags_evaltype' => CONDITION_EVAL_TYPE_AND_OR,
|
|
'tags' => [
|
|
[
|
|
'tag' => 'abc',
|
|
'operator' => CONDITION_OPERATOR_EQUAL,
|
|
'value' => '123'
|
|
],
|
|
[
|
|
'tag' => 'xyz',
|
|
'operator' => CONDITION_OPERATOR_EXISTS
|
|
]
|
|
]
|
|
],
|
|
'delete_single' => [
|
|
'name' => 'API test connector.delete - single',
|
|
'url' => 'http://localhost/'
|
|
],
|
|
'delete_multiple_1' => [
|
|
'name' => 'API test connector.delete - multiple 1',
|
|
'url' => 'http://localhost/'
|
|
],
|
|
'delete_multiple_2' => [
|
|
'name' => 'API test connector.delete - multiple 2',
|
|
'url' => 'http://localhost/'
|
|
]
|
|
];
|
|
$db_connectors = CDataHelper::call('connector.create', array_values($connectors));
|
|
|
|
$this->assertArrayHasKey('connectorids', $db_connectors,
|
|
__FUNCTION__.'() failed: Could not create connectors.'
|
|
);
|
|
|
|
self::$data['connectorids'] = array_combine(array_keys($connectors), $db_connectors['connectorids']);
|
|
}
|
|
|
|
/**
|
|
* Data provider for connector.create. Array contains invalid connectors.
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function getConnectorCreateDataInvalid(): array {
|
|
return [
|
|
'Test connector.create: empty request' => [
|
|
'connector' => [],
|
|
'expected_error' => 'Invalid parameter "/": cannot be empty.'
|
|
],
|
|
'Test connector.create: unexpected parameter' => [
|
|
'connector' => [
|
|
'abc' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1": unexpected parameter "abc".'
|
|
],
|
|
|
|
// Check "name".
|
|
'Test connector.create: missing "name"' => [
|
|
'connector' => [
|
|
'description' => ''
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1": the parameter "name" is missing.'
|
|
],
|
|
'Test connector.create: invalid "name" (empty string)' => [
|
|
'connector' => [
|
|
'name' => ''
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/name": cannot be empty.'
|
|
],
|
|
'Test connector.create: invalid "name" (too long)' => [
|
|
'connector' => [
|
|
'name' => str_repeat('a', DB::getFieldLength('connector', 'name') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/name": value is too long.'
|
|
],
|
|
'Test connector.create: multiple connectors with the same "name"' => [
|
|
'connector' => [
|
|
[
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/'
|
|
],
|
|
[
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/'
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/2": value (name)=(API create connector) already exists.'
|
|
],
|
|
'Test connector.create: invalid "name" (duplicate)' => [
|
|
'connector' => [
|
|
'name' => 'API test connector.get with custom defaults',
|
|
'url' => 'http://localhost/'
|
|
],
|
|
'expected_error' => 'Connector "API test connector.get with custom defaults" already exists.'
|
|
],
|
|
|
|
// Check "protocol".
|
|
'Test connector.create: invalid "protocol" (string)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'protocol' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/protocol": an integer is expected.'
|
|
],
|
|
'Test connector.create: invalid "protocol" (not in range)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'protocol' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/protocol": value must be 0.'
|
|
],
|
|
|
|
// Check "data_type".
|
|
'Test connector.create: invalid "data_type" (string)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'data_type' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/data_type": an integer is expected.'
|
|
],
|
|
'Test connector.create: invalid "data_type" (not in range)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'data_type' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/data_type": value must be one of '.
|
|
implode(', ', [ZBX_CONNECTOR_DATA_TYPE_ITEM_VALUES, ZBX_CONNECTOR_DATA_TYPE_EVENTS]).'.'
|
|
],
|
|
|
|
// Check "url".
|
|
'Test connector.create: missing "url"' => [
|
|
'connector' => [
|
|
'name' => 'API create connector'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1": the parameter "url" is missing.'
|
|
],
|
|
'Test connector.create: invalid "url" (boolean)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/url": a character string is expected.'
|
|
],
|
|
'Test connector.create: invalid "url" (empty string)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => ''
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/url": cannot be empty.'
|
|
],
|
|
'Test connector.create: invalid "url"' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'javascript:alert(123);'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/url": unacceptable URL.'
|
|
],
|
|
'Test connector.create: invalid "url" (too long)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => str_repeat('a', DB::getFieldLength('connector', 'url') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/url": value is too long.'
|
|
],
|
|
|
|
// Check "max_records".
|
|
'Test connector.create: invalid "max_records" (string)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'max_records' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/max_records": an integer is expected.'
|
|
],
|
|
'Test connector.create: invalid "max_records" (not in range)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'max_records' => -1
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/max_records": value must be one of 0-'.ZBX_MAX_INT32.'.'
|
|
],
|
|
|
|
// Check "max_senders".
|
|
'Test connector.create: invalid "max_senders" (string)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'max_senders' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/max_senders": an integer is expected.'
|
|
],
|
|
'Test connector.create: invalid "max_senders" (not in range)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'max_senders' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/max_senders": value must be one of 1-100.'
|
|
],
|
|
|
|
// Check "max_attempts".
|
|
'Test connector.create: invalid "max_attempts" (string)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'max_attempts' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/max_attempts": an integer is expected.'
|
|
],
|
|
'Test connector.create: invalid "max_attempts" (not in range)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'max_attempts' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/max_attempts": value must be one of 1-5.'
|
|
],
|
|
|
|
// Check "timeout".
|
|
'Test connector.create: invalid "timeout" (boolean)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'timeout' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/timeout": a character string is expected.'
|
|
],
|
|
'Test connector.create: invalid "timeout" (empty)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'timeout' => ''
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/timeout": cannot be empty.'
|
|
],
|
|
'Test connector.create: invalid "timeout" (string)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'timeout' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/timeout": a time unit is expected.'
|
|
],
|
|
'Test connector.create: invalid "timeout" (not in range)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'timeout' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/timeout": value must be one of 1-'.SEC_PER_MIN.'.'
|
|
],
|
|
|
|
// Check "http_proxy".
|
|
'Test connector.create: invalid "http_proxy" (boolean)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'http_proxy' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/http_proxy": a character string is expected.'
|
|
],
|
|
'Test connector.create: invalid "http_proxy" (too long)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'http_proxy' => str_repeat('a', DB::getFieldLength('connector', 'http_proxy') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/http_proxy": value is too long.'
|
|
],
|
|
|
|
// Check "authtype".
|
|
'Test connector.create: invalid "authtype" (string)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'authtype' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/authtype": an integer is expected.'
|
|
],
|
|
'Test connector.create: invalid "authtype" (not in range)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'authtype' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/authtype": value must be one of '.
|
|
implode(', ', [ZBX_HTTP_AUTH_NONE, ZBX_HTTP_AUTH_BASIC, ZBX_HTTP_AUTH_NTLM, ZBX_HTTP_AUTH_KERBEROS,
|
|
ZBX_HTTP_AUTH_DIGEST, ZBX_HTTP_AUTH_BEARER
|
|
]).'.'
|
|
],
|
|
|
|
// Check "username".
|
|
'Test connector.create: invalid "username" (must be empty)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'username' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/username": value must be empty.'
|
|
],
|
|
'Test connector.create: invalid "username" (boolean)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'authtype' => ZBX_HTTP_AUTH_BASIC,
|
|
'username' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/username": a character string is expected.'
|
|
],
|
|
'Test connector.create: invalid "username" (too long)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'authtype' => ZBX_HTTP_AUTH_NTLM,
|
|
'username' => str_repeat('a', DB::getFieldLength('connector', 'username') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/username": value is too long.'
|
|
],
|
|
|
|
// Check "password".
|
|
'Test connector.create: invalid "password" (must be empty)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'password' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/password": value must be empty.'
|
|
],
|
|
'Test connector.create: invalid "password" (boolean)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'authtype' => ZBX_HTTP_AUTH_BASIC,
|
|
'password' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/password": a character string is expected.'
|
|
],
|
|
'Test connector.create: invalid "password" (too long)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'authtype' => ZBX_HTTP_AUTH_NTLM,
|
|
'password' => str_repeat('a', DB::getFieldLength('connector', 'password') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/password": value is too long.'
|
|
],
|
|
|
|
// Check "token".
|
|
'Test connector.create: invalid "token" (boolean)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'token' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/token": a character string is expected.'
|
|
],
|
|
'Test connector.create: invalid "token" (incompatible authtype)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'token' => '{$BEARER_TOKEN}'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/token": value must be empty.'
|
|
],
|
|
'Test connector.create: invalid "token" (too long)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'authtype' => ZBX_HTTP_AUTH_BEARER,
|
|
'token' => str_repeat('a', DB::getFieldLength('connector', 'token') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/token": value is too long.'
|
|
],
|
|
|
|
// Check "verify_peer".
|
|
'Test connector.create: invalid "verify_peer" (string)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'verify_peer' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/verify_peer": an integer is expected.'
|
|
],
|
|
'Test connector.create: invalid "verify_peer" (not in range)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'verify_peer' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/verify_peer": value must be one of '.
|
|
implode(', ', [ZBX_HTTP_VERIFY_PEER_OFF, ZBX_HTTP_VERIFY_PEER_ON]).'.'
|
|
],
|
|
|
|
// Check "verify_host".
|
|
'Test connector.create: invalid "verify_host" (string)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'verify_host' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/verify_host": an integer is expected.'
|
|
],
|
|
'Test connector.create: invalid "verify_host" (not in range)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'verify_host' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/verify_host": value must be one of '.
|
|
implode(', ', [ZBX_HTTP_VERIFY_HOST_OFF, ZBX_HTTP_VERIFY_HOST_ON]).'.'
|
|
],
|
|
|
|
// Check "ssl_cert_file".
|
|
'Test connector.create: invalid "ssl_cert_file" (boolean)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'ssl_cert_file' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/ssl_cert_file": a character string is expected.'
|
|
],
|
|
'Test connector.create: invalid "ssl_cert_file" (too long)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'ssl_cert_file' => str_repeat('a', DB::getFieldLength('connector', 'ssl_cert_file') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/ssl_cert_file": value is too long.'
|
|
],
|
|
|
|
// Check "ssl_key_file".
|
|
'Test connector.create: invalid "ssl_key_file" (boolean)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'ssl_cert_file' => 'ssl_cert_file',
|
|
'ssl_key_file' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/ssl_key_file": a character string is expected.'
|
|
],
|
|
'Test connector.create: invalid "ssl_key_file" (too long)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'ssl_cert_file' => 'ssl_cert_file',
|
|
'ssl_key_file' => str_repeat('a', DB::getFieldLength('connector', 'ssl_key_file') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/ssl_key_file": value is too long.'
|
|
],
|
|
|
|
// Check "ssl_key_password".
|
|
'Test connector.create: invalid "ssl_key_password" (boolean)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'ssl_cert_file' => 'ssl_cert_file',
|
|
'ssl_key_file' => 'ssl_key_file',
|
|
'ssl_key_password' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/ssl_key_password": a character string is expected.'
|
|
],
|
|
'Test connector.create: invalid "ssl_key_password" (too long)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'ssl_cert_file' => 'ssl_cert_file',
|
|
'ssl_key_file' => 'ssl_key_file',
|
|
'ssl_key_password' => str_repeat('a', DB::getFieldLength('connector', 'ssl_key_password') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/ssl_key_password": value is too long.'
|
|
],
|
|
|
|
// Check "description".
|
|
'Test connector.create: invalid "description" (boolean)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'description' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/description": a character string is expected.'
|
|
],
|
|
'Test connector.create: invalid "description" (too long)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'description' => str_repeat('a', DB::getFieldLength('connector', 'description') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/description": value is too long.'
|
|
],
|
|
|
|
// Check "status".
|
|
'Test connector.create: invalid "status" (string)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'status' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/status": an integer is expected.'
|
|
],
|
|
'Test connector.create: invalid "status" (not in range)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'status' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/status": value must be one of '.
|
|
implode(', ', [ZBX_CONNECTOR_STATUS_DISABLED, ZBX_CONNECTOR_STATUS_ENABLED]).'.'
|
|
],
|
|
|
|
// Check "tags_evaltype".
|
|
'Test connector.create: invalid "tags_evaltype" (string)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'tags_evaltype' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags_evaltype": an integer is expected.'
|
|
],
|
|
'Test connector.create: invalid "tags_evaltype" (not in range)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'tags_evaltype' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags_evaltype": value must be one of '.
|
|
implode(', ', [CONDITION_EVAL_TYPE_AND_OR, CONDITION_EVAL_TYPE_OR]).'.'
|
|
],
|
|
|
|
// Check "tags".
|
|
'Test connector.create: invalid "tags" (string)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'tags' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags": an array is expected.'
|
|
],
|
|
'Test connector.create: invalid "tags" (array with string)' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'tags' => ['abc']
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1": an array is expected.'
|
|
],
|
|
'Test connector.create: missing "tag" for "tags"' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'tags' => [
|
|
[]
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1": the parameter "tag" is missing.'
|
|
],
|
|
'Test connector.create: unexpected parameter for "tags"' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'tags' => [
|
|
['abc' => '']
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1": unexpected parameter "abc".'
|
|
],
|
|
'Test connector.create: invalid "tag" (boolean) for "tags"' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'tags' => [
|
|
['tag' => false]
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/tag": a character string is expected.'
|
|
],
|
|
'Test connector.create: invalid "tag" (empty string) for "tags"' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'tags' => [
|
|
['tag' => '']
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/tag": cannot be empty.'
|
|
],
|
|
'Test connector.create: invalid "tag" (too long) for "tags"' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'tags' => [
|
|
['tag' => str_repeat('a', DB::getFieldLength('connector_tag', 'tag') + 1)]
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/tag": value is too long.'
|
|
],
|
|
'Test connector.create: invalid "operator" (boolean) for "tags"' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'tags' => [
|
|
['tag' => 'abc', 'operator' => false]
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/operator": an integer is expected.'
|
|
],
|
|
'Test connector.create: invalid "operator" (not in range) for "tags"' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'tags' => [
|
|
['tag' => 'abc', 'operator' => self::INVALID_NUMBER]
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/operator": value must be one of '.
|
|
implode(', ', [CONDITION_OPERATOR_EQUAL, CONDITION_OPERATOR_NOT_EQUAL, CONDITION_OPERATOR_LIKE,
|
|
CONDITION_OPERATOR_NOT_LIKE, CONDITION_OPERATOR_EXISTS, CONDITION_OPERATOR_NOT_EXISTS
|
|
]).'.'
|
|
],
|
|
'Test connector.create: invalid "value" (boolean) for "tags"' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'tags' => [
|
|
['tag' => 'abc', 'operator' => CONDITION_OPERATOR_EQUAL, 'value' => false]
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/value": a character string is expected.'
|
|
],
|
|
'Test connector.create: invalid "value" (not empty) for "tags"' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'tags' => [
|
|
['tag' => 'abc', 'operator' => CONDITION_OPERATOR_EXISTS, 'value' => '123']
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/value": value must be empty.'
|
|
],
|
|
'Test connector.create: invalid "value" (not empty) for "tags" 2' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'tags' => [
|
|
['tag' => 'abc', 'operator' => CONDITION_OPERATOR_NOT_EXISTS, 'value' => '123']
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/value": value must be empty.'
|
|
],
|
|
'Test connector.create: invalid "value" (too long) for "tags"' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'tags' => [
|
|
[
|
|
'tag' => 'abc',
|
|
'operator' => CONDITION_OPERATOR_EQUAL,
|
|
'value' => str_repeat('a', DB::getFieldLength('connector_tag', 'value') + 1)
|
|
]
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/value": value is too long.'
|
|
],
|
|
'Test connector.create: invalid "tag" (duplicate) for "tags"' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'tags' => [
|
|
['tag' => 'abc', 'operator' => CONDITION_OPERATOR_EQUAL, 'value' => '123'],
|
|
['tag' => 'abc', 'operator' => CONDITION_OPERATOR_EQUAL, 'value' => '123']
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/2": value (tag, operator, value)=(abc, 0, 123) already exists.'
|
|
],
|
|
'Test connector.create: overly long username' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'authtype' => ZBX_HTTP_AUTH_BASIC,
|
|
'username' => str_repeat('z', 256)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/username": value is too long.'
|
|
],
|
|
'Test connector.create: overly long password' => [
|
|
'connector' => [
|
|
'name' => 'API create connector',
|
|
'url' => 'http://localhost/',
|
|
'authtype' => ZBX_HTTP_AUTH_BASIC,
|
|
'password' => str_repeat('z', 256)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/password": value is too long.'
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Data provider for connector.create. Array contains valid connectors.
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function getConnectorCreateDataValid(): array {
|
|
return [
|
|
'Test connector.create: single connector' => [
|
|
'connector' => [
|
|
'name' => 'API create single connector',
|
|
'url' => 'http://localhost/'
|
|
],
|
|
'expected_error' => null
|
|
],
|
|
'Test connector.create: multiple connectors' => [
|
|
'connector' => [
|
|
[
|
|
'name' => 'API create first connector',
|
|
'url' => 'http://localhost/'
|
|
],
|
|
[
|
|
'name' => 'API create second connector',
|
|
'url' => 'http://localhost/'
|
|
]
|
|
],
|
|
'expected_error' => null
|
|
],
|
|
'Test connector.create: longest username' => [
|
|
'connector' => [
|
|
'name' => 'API longest username connector',
|
|
'url' => 'http://localhost/',
|
|
'authtype' => ZBX_HTTP_AUTH_BASIC,
|
|
'username' => str_repeat('z', 255)
|
|
],
|
|
'expected_error' => null
|
|
],
|
|
'Test connector.create: longest password' => [
|
|
'connector' => [
|
|
'name' => 'API longest password connector',
|
|
'url' => 'http://localhost/',
|
|
'authtype' => ZBX_HTTP_AUTH_BASIC,
|
|
'password' => str_repeat('z', 255)
|
|
],
|
|
'expected_error' => null
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Test connector.create with errors like missing fields, optional invalid fields and valid fields.
|
|
*
|
|
* @dataProvider getConnectorCreateDataInvalid
|
|
* @dataProvider getConnectorCreateDataValid
|
|
*/
|
|
public function testConnector_Create(array $connectors, ?string $expected_error): void {
|
|
// Accept single and multiple connectors just like API method. Work with multidimensional array in result.
|
|
if (!array_key_exists(0, $connectors)) {
|
|
$connectors = zbx_toArray($connectors);
|
|
}
|
|
|
|
$sql_connectors = 'SELECT NULL FROM connector';
|
|
$old_hash_connectors = CDBHelper::getHash($sql_connectors);
|
|
|
|
$result = $this->call('connector.create', $connectors, $expected_error);
|
|
|
|
if ($expected_error === null) {
|
|
// Something was changed in DB.
|
|
$this->assertNotSame($old_hash_connectors, CDBHelper::getHash($sql_connectors));
|
|
$this->assertEquals(count($connectors), count($result['result']['connectorids']));
|
|
|
|
// Add connector IDs to create array, so they can be deleted after tests are complete.
|
|
self::$data['created'] = array_merge(self::$data['created'], $result['result']['connectorids']);
|
|
|
|
$db_connectors = $this->getConnectors($result['result']['connectorids']);
|
|
$db_defaults = DB::getDefaults('connector');
|
|
|
|
// Check individual fields.
|
|
foreach ($result['result']['connectorids'] as $num => $connectorid) {
|
|
$connector = $connectors[$num];
|
|
$db_connector = $db_connectors[$connectorid];
|
|
|
|
// Required fields.
|
|
$this->assertNotEmpty($db_connector['name']);
|
|
$this->assertSame($connector['name'], $db_connector['name']);
|
|
$this->assertNotEmpty($db_connector['url']);
|
|
$this->assertSame($connector['url'], $db_connector['url']);
|
|
|
|
// Numeric fields.
|
|
foreach (['protocol', 'data_type', 'max_records', 'max_senders', 'max_attempts', 'authtype',
|
|
'verify_peer', 'verify_host', 'status', 'tags_evaltype'] as $field) {
|
|
if (array_key_exists($field, $connector)) {
|
|
$this->assertEquals($connector[$field], $db_connector[$field]);
|
|
}
|
|
else {
|
|
$this->assertEquals($db_defaults[$field], $db_connector[$field]);
|
|
}
|
|
}
|
|
|
|
// Text fields.
|
|
if (array_key_exists('timeout', $connector)) {
|
|
$this->assertSame($connector['timeout'], $db_connector['timeout']);
|
|
}
|
|
else {
|
|
$this->assertSame($db_defaults['timeout'], $db_connector['timeout']);
|
|
}
|
|
|
|
foreach (['http_proxy', 'ssl_cert_file', 'ssl_key_file', 'ssl_key_password', 'description'] as $field) {
|
|
if (array_key_exists($field, $connector)) {
|
|
$this->assertSame($connector[$field], $db_connector[$field]);
|
|
}
|
|
else {
|
|
$this->assertEmpty($db_connector[$field]);
|
|
}
|
|
}
|
|
|
|
if (in_array($db_connector['authtype'], [ZBX_HTTP_AUTH_BASIC, ZBX_HTTP_AUTH_NTLM,
|
|
ZBX_HTTP_AUTH_KERBEROS, ZBX_HTTP_AUTH_DIGEST])) {
|
|
foreach (['username', 'password'] as $field) {
|
|
if (array_key_exists($field, $connector)) {
|
|
$this->assertSame($connector[$field], $db_connector[$field]);
|
|
}
|
|
else {
|
|
$this->assertEmpty($db_connector[$field]);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$this->assertEmpty($db_connector['username']);
|
|
$this->assertEmpty($db_connector['password']);
|
|
}
|
|
|
|
if ($db_connector['authtype'] == ZBX_HTTP_AUTH_BEARER) {
|
|
$this->assertNotEmpty($db_connector['token']);
|
|
$this->assertSame($connector['token'], $db_connector['token']);
|
|
}
|
|
else {
|
|
$this->assertEmpty($db_connector['token']);
|
|
}
|
|
|
|
// Tags.
|
|
if (array_key_exists('tags', $connector) && $connector['tags']) {
|
|
$this->assertEqualsCanonicalizing($connector['tags'], $db_connector['tags']);
|
|
}
|
|
else {
|
|
$this->assertEmpty($db_connector['tags']);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$this->assertSame($old_hash_connectors, CDBHelper::getHash($sql_connectors));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Data provider for connector.get. Array contains invalid connector parameters.
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function getConnectorGetDataInvalid(): array {
|
|
return [
|
|
// Check unexpected params.
|
|
'Test connector.get: unexpected parameter' => [
|
|
'request' => [
|
|
'abc' => 'abc'
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/": unexpected parameter "abc".'
|
|
],
|
|
|
|
// Check "connectorids" field.
|
|
'Test connector.get: invalid "connectorids" (empty string)' => [
|
|
'request' => [
|
|
'connectorids' => ''
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/connectorids": an array is expected.'
|
|
],
|
|
'Test connector.get: invalid "connectorids" (array with empty string)' => [
|
|
'request' => [
|
|
'connectorids' => ['']
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/connectorids/1": a number is expected.'
|
|
],
|
|
|
|
// Check filter.
|
|
'Test connector.get: invalid "filter" (empty string)' => [
|
|
'request' => [
|
|
'filter' => ''
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/filter": an array is expected.'
|
|
],
|
|
|
|
// Check unexpected parameters that exist in object, but not in filter.
|
|
'Test connector.get: unexpected parameter in "filter"' => [
|
|
'request' => [
|
|
'filter' => [
|
|
'max_records' => 'max_records'
|
|
]
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/filter": unexpected parameter "max_records".'
|
|
],
|
|
|
|
// Check "search" option.
|
|
'Test connector.get: invalid "search" (string)' => [
|
|
'request' => [
|
|
'search' => 'abc'
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/search": an array is expected.'
|
|
],
|
|
|
|
// Check unexpected parameters that exist in object, but not in search.
|
|
'Test connector.get: unexpected parameter in "search"' => [
|
|
'request' => [
|
|
'search' => [
|
|
'connectorid' => 'connectorid'
|
|
]
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/search": unexpected parameter "connectorid".'
|
|
],
|
|
|
|
// Check "output" option.
|
|
'Test connector.get: invalid parameter "output" (string)' => [
|
|
'request' => [
|
|
'output' => 'abc'
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/output": value must be "'.API_OUTPUT_EXTEND.'".'
|
|
],
|
|
'Test connector.get: invalid parameter "output" (array with string)' => [
|
|
'request' => [
|
|
'output' => ['abc']
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/output/1": value must be one of "connectorid", "name", "protocol", "data_type", "url", "max_records", "max_senders", "max_attempts", "timeout", "http_proxy", "authtype", "username", "password", "token", "verify_peer", "verify_host", "ssl_cert_file", "ssl_key_file", "ssl_key_password", "description", "status", "tags_evaltype".'
|
|
],
|
|
|
|
// Check "selectTags" option.
|
|
'Test connector.get: invalid parameter "selectTags" (string)' => [
|
|
'request' => [
|
|
'selectTags' => 'abc'
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/selectTags": value must be one of "'.API_OUTPUT_EXTEND.'", "'.API_OUTPUT_COUNT.'".'
|
|
],
|
|
'Test connector.get: invalid parameter "selectTags" (array with string)' => [
|
|
'request' => [
|
|
'selectTags' => ['abc']
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/selectTags/1": value must be one of "tag", "operator", "value".'
|
|
],
|
|
|
|
// Check common fields that are not flags, but require strict validation.
|
|
'Test connector.get: invalid parameter "searchByAny" (string)' => [
|
|
'request' => [
|
|
'searchByAny' => 'abc'
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/searchByAny": a boolean is expected.'
|
|
],
|
|
'Test connector.get: invalid parameter "searchWildcardsEnabled" (string)' => [
|
|
'request' => [
|
|
'searchWildcardsEnabled' => 'abc'
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/searchWildcardsEnabled": a boolean is expected.'
|
|
],
|
|
'Test connector.get: invalid parameter "sortfield" (bool)' => [
|
|
'request' => [
|
|
'sortfield' => false
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/sortfield": an array is expected.'
|
|
],
|
|
'Test connector.get: invalid parameter "sortfield"' => [
|
|
'request' => [
|
|
'sortfield' => 'abc'
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/sortfield/1": value must be one of "connectorid", "name", "data_type", "status".'
|
|
],
|
|
'Test connector.get: invalid parameter "sortorder" (bool)' => [
|
|
'request' => [
|
|
'sortorder' => false
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/sortorder": an array or a character string is expected.'
|
|
],
|
|
'Test connector.get: invalid parameter "sortorder" (not in range)' => [
|
|
'request' => [
|
|
'sortorder' => 'abc'
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' =>
|
|
'Invalid parameter "/sortorder": value must be one of "'.ZBX_SORT_UP.'", "'.ZBX_SORT_DOWN.'".'
|
|
],
|
|
'Test connector.get: invalid parameter "limit" (bool)' => [
|
|
'request' => [
|
|
'limit' => false
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/limit": an integer is expected.'
|
|
],
|
|
'Test connector.get: invalid parameter "preservekeys" (string)' => [
|
|
'request' => [
|
|
'preservekeys' => 'abc'
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => 'Invalid parameter "/preservekeys": a boolean is expected.'
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Data provider for connector.get. Array contains valid connector parameters.
|
|
*,
|
|
* @return array
|
|
*/
|
|
public static function getConnectorGetDataValid(): array {
|
|
return [
|
|
// Check validity of "connectorids" without getting any results.
|
|
'Test connector.get: empty "connectorids"' => [
|
|
'request' => [
|
|
'connectorids' => []
|
|
],
|
|
'expected_result' => [],
|
|
'expected_error' => null
|
|
],
|
|
|
|
// Check no fields are returned on empty selection.
|
|
'Test connector.get: empty "output"' => [
|
|
'request' => [
|
|
'output' => [],
|
|
'connectorids' => ['get_custom_defaults', 'get_status_disabled']
|
|
],
|
|
'expected_result' => [
|
|
[],
|
|
[]
|
|
],
|
|
'expected_error' => null
|
|
],
|
|
|
|
// Check only specific fields are returned.
|
|
'Test connector.get: specific field "output"' => [
|
|
'request' => [
|
|
'output' => ['connectorid', 'name', 'url'],
|
|
'connectorids' => ['get_custom_defaults']
|
|
],
|
|
'expected_result' => [
|
|
[
|
|
'connectorid' => 'get_custom_defaults',
|
|
'name' => 'API test connector.get with custom defaults',
|
|
'url' => 'http://localhost/'
|
|
]
|
|
],
|
|
'expected_error' => null
|
|
],
|
|
|
|
// Filter by data type.
|
|
'Test connector.get: filter by "data_type"' => [
|
|
'request' => [
|
|
'output' => ['name', 'data_type'],
|
|
'connectorids' => ['get_custom_defaults', 'get_data_type_events'],
|
|
'filter' => [
|
|
'data_type' => ZBX_CONNECTOR_DATA_TYPE_EVENTS
|
|
]
|
|
],
|
|
'expected_result' => [
|
|
[
|
|
'name' => 'API test connector.get with data type (events)',
|
|
'data_type' => (string) ZBX_CONNECTOR_DATA_TYPE_EVENTS
|
|
]
|
|
],
|
|
'expected_error' => null
|
|
],
|
|
|
|
// Filter by authentication type.
|
|
'Test connector.get: filter by "authtype"' => [
|
|
'request' => [
|
|
'output' => ['name', 'authtype', 'username', 'password'],
|
|
'connectorids' => ['get_custom_defaults', 'get_authtype_basic'],
|
|
'filter' => [
|
|
'authtype' => ZBX_HTTP_AUTH_BASIC
|
|
]
|
|
],
|
|
'expected_result' => [
|
|
[
|
|
'name' => 'API test connector.get with authtype (basic), username and password',
|
|
'authtype' => (string) ZBX_HTTP_AUTH_BASIC,
|
|
'username' => 'test',
|
|
'password' => '12345678'
|
|
]
|
|
],
|
|
'expected_error' => null
|
|
],
|
|
|
|
// Filter by status.
|
|
'Test connector.get: filter by "status"' => [
|
|
'request' => [
|
|
'output' => ['name', 'status'],
|
|
'connectorids' => ['get_custom_defaults', 'get_status_disabled'],
|
|
'filter' => [
|
|
'status' => ZBX_CONNECTOR_STATUS_DISABLED
|
|
]
|
|
],
|
|
'expected_result' => [
|
|
[
|
|
'name' => 'API test connector.get with status (disabled)',
|
|
'status' => (string) ZBX_CONNECTOR_STATUS_DISABLED
|
|
]
|
|
],
|
|
'expected_error' => null
|
|
],
|
|
|
|
// Search by name.
|
|
'Test connector.get: search by "name"' => [
|
|
'request' => [
|
|
'output' => ['name'],
|
|
'search' => [
|
|
'name' => 'API test connector.get with custom defaults'
|
|
]
|
|
],
|
|
'expected_result' => [
|
|
[
|
|
'name' => 'API test connector.get with custom defaults'
|
|
]
|
|
],
|
|
'expected_error' => null
|
|
],
|
|
|
|
// Search by URL.
|
|
'Test connector.get: search by "url"' => [
|
|
'request' => [
|
|
'output' => ['name', 'url'],
|
|
'search' => [
|
|
'url' => '{$URL}'
|
|
]
|
|
],
|
|
'expected_result' => [
|
|
[
|
|
'name' => 'API test connector.get with URL (user macro)',
|
|
'url' => '{$URL}'
|
|
]
|
|
],
|
|
'expected_error' => null
|
|
],
|
|
|
|
// Search by HTTP proxy.
|
|
'Test connector.get: search by "http_proxy"' => [
|
|
'request' => [
|
|
'output' => ['name', 'http_proxy'],
|
|
'search' => [
|
|
'http_proxy' => '{$HTTP_PROXY}'
|
|
]
|
|
],
|
|
'expected_result' => [
|
|
[
|
|
'name' => 'API test connector.get with HTTP proxy (user macro)',
|
|
'http_proxy' => '{$HTTP_PROXY}'
|
|
]
|
|
],
|
|
'expected_error' => null
|
|
],
|
|
|
|
// Search by username.
|
|
'Test connector.get: search by "username"' => [
|
|
'request' => [
|
|
'output' => ['name', 'authtype', 'username', 'password'],
|
|
'connectorids' => ['get_custom_defaults', 'get_authtype_basic'],
|
|
'search' => [
|
|
'username' => 'test'
|
|
]
|
|
],
|
|
'expected_result' => [
|
|
[
|
|
'name' => 'API test connector.get with authtype (basic), username and password',
|
|
'authtype' => (string) ZBX_HTTP_AUTH_BASIC,
|
|
'username' => 'test',
|
|
'password' => '12345678'
|
|
]
|
|
],
|
|
'expected_error' => null
|
|
],
|
|
|
|
// Search by Bearer token.
|
|
'Test connector.get: search by "token"' => [
|
|
'request' => [
|
|
'output' => ['name', 'authtype', 'token'],
|
|
'search' => [
|
|
'token' => '{$BEARER_TOKEN}'
|
|
]
|
|
],
|
|
'expected_result' => [
|
|
[
|
|
'name' => 'API test connector.get with authtype (bearer)',
|
|
'authtype' => (string) ZBX_HTTP_AUTH_BEARER,
|
|
'token' => '{$BEARER_TOKEN}'
|
|
]
|
|
],
|
|
'expected_error' => null
|
|
],
|
|
|
|
// Search by description.
|
|
'Test connector.get: search by "description"' => [
|
|
'request' => [
|
|
'output' => ['name', 'description'],
|
|
'search' => [
|
|
'description' => 'Custom description'
|
|
]
|
|
],
|
|
'expected_result' => [
|
|
[
|
|
'name' => 'API test connector.get with custom defaults',
|
|
'description' => 'Custom description'
|
|
]
|
|
],
|
|
'expected_error' => null
|
|
],
|
|
|
|
// Check tags are returned.
|
|
'Test connector.get: tags' => [
|
|
'request' => [
|
|
'output' => ['connectorid', 'name'],
|
|
'selectTags' => ['tag', 'operator', 'value'],
|
|
'connectorids' => ['get_custom_defaults', 'get_tags']
|
|
],
|
|
'expected_result' => [
|
|
[
|
|
'connectorid' => 'get_custom_defaults',
|
|
'name' => 'API test connector.get with custom defaults',
|
|
'tags' => []
|
|
],
|
|
[
|
|
'connectorid' => 'get_tags',
|
|
'name' => 'API test connector.get with two tags',
|
|
'tags' => [
|
|
[
|
|
'tag' => 'abc',
|
|
'operator' => (string) CONDITION_OPERATOR_EQUAL,
|
|
'value' => '123'
|
|
],
|
|
[
|
|
'tag' => 'xyz',
|
|
'operator' => (string) CONDITION_OPERATOR_EXISTS,
|
|
'value' => ''
|
|
]
|
|
]
|
|
]
|
|
],
|
|
'expected_error' => null
|
|
],
|
|
|
|
// Check tag count is returned.
|
|
'Test connector.get: tag count' => [
|
|
'request' => [
|
|
'output' => ['connectorid', 'name'],
|
|
'selectTags' => API_OUTPUT_COUNT,
|
|
'connectorids' => ['get_custom_defaults', 'get_tags']
|
|
],
|
|
'expected_result' => [
|
|
[
|
|
'connectorid' => 'get_custom_defaults',
|
|
'name' => 'API test connector.get with custom defaults',
|
|
'tags' => '0'
|
|
],
|
|
[
|
|
'connectorid' => 'get_tags',
|
|
'name' => 'API test connector.get with two tags',
|
|
'tags' => '2'
|
|
]
|
|
],
|
|
'expected_error' => null
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Test connector.get with all options.
|
|
*
|
|
* @dataProvider getConnectorGetDataInvalid
|
|
* @dataProvider getConnectorGetDataValid
|
|
*/
|
|
public function testConnector_Get(array $request, array $expected_result, ?string $expected_error): void {
|
|
// Replace ID placeholders with real IDs.
|
|
$request = self::resolveIds($request);
|
|
|
|
foreach ($expected_result as &$connector) {
|
|
$connector = self::resolveIds($connector);
|
|
}
|
|
unset($connector);
|
|
|
|
$result = $this->call('connector.get', $request, $expected_error);
|
|
|
|
if ($expected_error === null) {
|
|
$this->assertSame($expected_result, $result['result']);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Data provider for connector.update. Array contains invalid connector parameters.
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function getConnectorUpdateDataInvalid(): array {
|
|
return [
|
|
'Test connector.update: empty request' => [
|
|
'connector' => [],
|
|
'expected_error' => 'Invalid parameter "/": cannot be empty.'
|
|
],
|
|
|
|
// Check "connectorid".
|
|
'Test connector.update: missing "connectorid"' => [
|
|
'connector' => [
|
|
'name' => 'API update connector'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1": the parameter "connectorid" is missing.'
|
|
],
|
|
'Test connector.update: invalid "connectorid" (empty string)' => [
|
|
'connector' => [
|
|
'connectorid' => ''
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/connectorid": a number is expected.'
|
|
],
|
|
'Test connector.update: invalid "connectorid" (non-existent)' => [
|
|
'connector' => [
|
|
'connectorid' => self::INVALID_ID
|
|
],
|
|
'expected_error' => 'No permissions to referred object or it does not exist!'
|
|
],
|
|
'Test connector.update: multiple connectors with the same "connectorid"' => [
|
|
'connector' => [
|
|
['connectorid' => 0],
|
|
['connectorid' => 0]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/2": value (connectorid)=(0) already exists.'
|
|
],
|
|
|
|
// Check "name".
|
|
'Test connector.update: invalid "name" (empty string)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'name' => ''
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/name": cannot be empty.'
|
|
],
|
|
'Test connector.update: invalid "name" (too long)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'name' => str_repeat('a', DB::getFieldLength('connector', 'name') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/name": value is too long.'
|
|
],
|
|
|
|
// Check "protocol".
|
|
'Test connector.update: invalid "protocol" (string)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'protocol' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/protocol": an integer is expected.'
|
|
],
|
|
'Test connector.update: invalid "protocol" (not in range)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'protocol' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/protocol": value must be 0.'
|
|
],
|
|
|
|
// Check "data_type".
|
|
'Test connector.update: invalid "data_type" (string)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'data_type' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/data_type": an integer is expected.'
|
|
],
|
|
'Test connector.update: invalid "data_type" (not in range)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'data_type' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/data_type": value must be one of '.
|
|
implode(', ', [ZBX_CONNECTOR_DATA_TYPE_ITEM_VALUES, ZBX_CONNECTOR_DATA_TYPE_EVENTS]).'.'
|
|
],
|
|
|
|
// Check "url".
|
|
'Test connector.update: invalid "url" (boolean)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'url' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/url": a character string is expected.'
|
|
],
|
|
'Test connector.update: invalid "url" (empty string)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'url' => ''
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/url": cannot be empty.'
|
|
],
|
|
'Test connector.update: invalid "url"' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'url' => 'javascript:alert(123);'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/url": unacceptable URL.'
|
|
],
|
|
'Test connector.update: invalid "url" (too long)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'url' => str_repeat('a', DB::getFieldLength('connector', 'url') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/url": value is too long.'
|
|
],
|
|
|
|
// Check "max_records".
|
|
'Test connector.update: invalid "max_records" (string)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'max_records' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/max_records": an integer is expected.'
|
|
],
|
|
'Test connector.update: invalid "max_records" (not in range)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'max_records' => -1
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/max_records": value must be one of 0-'.ZBX_MAX_INT32.'.'
|
|
],
|
|
|
|
// Check "max_senders".
|
|
'Test connector.update: invalid "max_senders" (string)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'max_senders' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/max_senders": an integer is expected.'
|
|
],
|
|
'Test connector.update: invalid "max_senders" (not in range)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'max_senders' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/max_senders": value must be one of 1-100.'
|
|
],
|
|
|
|
// Check "max_attempts".
|
|
'Test connector.update: invalid "max_attempts" (string)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'max_attempts' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/max_attempts": an integer is expected.'
|
|
],
|
|
'Test connector.update: invalid "max_attempts" (not in range)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'max_attempts' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/max_attempts": value must be one of 1-5.'
|
|
],
|
|
|
|
// Check "timeout".
|
|
'Test connector.update: invalid "timeout" (boolean)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'timeout' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/timeout": a character string is expected.'
|
|
],
|
|
'Test connector.update: invalid "timeout" (empty)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'timeout' => ''
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/timeout": cannot be empty.'
|
|
],
|
|
'Test connector.update: invalid "timeout" (string)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'timeout' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/timeout": a time unit is expected.'
|
|
],
|
|
'Test connector.update: invalid "timeout" (not in range)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'timeout' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/timeout": value must be one of 1-'.SEC_PER_MIN.'.'
|
|
],
|
|
|
|
// Check "http_proxy".
|
|
'Test connector.update: invalid "http_proxy" (boolean)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'http_proxy' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/http_proxy": a character string is expected.'
|
|
],
|
|
'Test connector.update: invalid "http_proxy" (too long)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'http_proxy' => str_repeat('a', DB::getFieldLength('connector', 'http_proxy') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/http_proxy": value is too long.'
|
|
],
|
|
|
|
// Check "authtype".
|
|
'Test connector.update: invalid "authtype" (string)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'authtype' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/authtype": an integer is expected.'
|
|
],
|
|
'Test connector.update: invalid "authtype" (not in range)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'authtype' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/authtype": value must be one of '.
|
|
implode(', ', [ZBX_HTTP_AUTH_NONE, ZBX_HTTP_AUTH_BASIC, ZBX_HTTP_AUTH_NTLM, ZBX_HTTP_AUTH_KERBEROS,
|
|
ZBX_HTTP_AUTH_DIGEST, ZBX_HTTP_AUTH_BEARER
|
|
]).'.'
|
|
],
|
|
|
|
// Check "username".
|
|
'Test connector.update: invalid "username" (must be empty)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'username' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/username": value must be empty.'
|
|
],
|
|
'Test connector.update: invalid "username" (boolean)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_authtype_basic',
|
|
'username' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/username": a character string is expected.'
|
|
],
|
|
'Test connector.update: invalid "username" (too long)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_authtype_basic',
|
|
'username' => str_repeat('a', DB::getFieldLength('connector', 'username') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/username": value is too long.'
|
|
],
|
|
|
|
// Check "password".
|
|
'Test connector.update: invalid "password" (must be empty)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'password' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/password": value must be empty.'
|
|
],
|
|
'Test connector.update: invalid "password" (boolean)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_authtype_basic',
|
|
'password' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/password": a character string is expected.'
|
|
],
|
|
'Test connector.update: invalid "password" (too long)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_authtype_basic',
|
|
'password' => str_repeat('a', DB::getFieldLength('connector', 'password') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/password": value is too long.'
|
|
],
|
|
|
|
// Check "token".
|
|
'Test connector.update: invalid "token" (boolean)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_authtype_basic',
|
|
'token' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/token": a character string is expected.'
|
|
],
|
|
'Test connector.update: invalid "token" (incompatible authtype)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_authtype_basic',
|
|
'token' => '{$BEARER_TOKEN}'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/token": value must be empty.'
|
|
],
|
|
'Test connector.update: invalid "token" (too long)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_authtype_basic',
|
|
'authtype' => ZBX_HTTP_AUTH_BEARER,
|
|
'token' => str_repeat('a', DB::getFieldLength('connector', 'token') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/token": value is too long.'
|
|
],
|
|
|
|
// Check "verify_peer".
|
|
'Test connector.update: invalid "verify_peer" (string)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'verify_peer' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/verify_peer": an integer is expected.'
|
|
],
|
|
'Test connector.update: invalid "verify_peer" (not in range)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'verify_peer' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/verify_peer": value must be one of '.
|
|
implode(', ', [ZBX_HTTP_VERIFY_PEER_OFF, ZBX_HTTP_VERIFY_PEER_ON]).'.'
|
|
],
|
|
|
|
// Check "verify_host".
|
|
'Test connector.update: invalid "verify_host" (string)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'verify_host' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/verify_host": an integer is expected.'
|
|
],
|
|
'Test connector.update: invalid "verify_host" (not in range)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'verify_host' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/verify_host": value must be one of '.
|
|
implode(', ', [ZBX_HTTP_VERIFY_HOST_OFF, ZBX_HTTP_VERIFY_HOST_ON]).'.'
|
|
],
|
|
|
|
// Check "ssl_cert_file".
|
|
'Test connector.update: invalid "ssl_cert_file" (boolean)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'ssl_cert_file' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/ssl_cert_file": a character string is expected.'
|
|
],
|
|
'Test connector.update: invalid "ssl_cert_file" (too long)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'ssl_cert_file' => str_repeat('a', DB::getFieldLength('connector', 'ssl_cert_file') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/ssl_cert_file": value is too long.'
|
|
],
|
|
|
|
// Check "ssl_key_file".
|
|
'Test connector.update: invalid "ssl_key_file" (boolean)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'ssl_key_file' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/ssl_key_file": a character string is expected.'
|
|
],
|
|
'Test connector.update: invalid "ssl_key_file" (too long)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'ssl_key_file' => str_repeat('a', DB::getFieldLength('connector', 'ssl_key_file') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/ssl_key_file": value is too long.'
|
|
],
|
|
|
|
// Check "ssl_key_password".
|
|
'Test connector.update: invalid "ssl_key_password" (boolean)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'ssl_key_password' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/ssl_key_password": a character string is expected.'
|
|
],
|
|
'Test connector.update: invalid "ssl_key_password" (too long)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'ssl_key_password' => str_repeat('a', DB::getFieldLength('connector', 'ssl_key_password') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/ssl_key_password": value is too long.'
|
|
],
|
|
|
|
// Check "description".
|
|
'Test connector.update: invalid "description" (boolean)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'description' => false
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/description": a character string is expected.'
|
|
],
|
|
'Test connector.update: invalid "description" (too long)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'description' => str_repeat('a', DB::getFieldLength('connector', 'description') + 1)
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/description": value is too long.'
|
|
],
|
|
|
|
// Check "status".
|
|
'Test connector.update: invalid "status" (string)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'status' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/status": an integer is expected.'
|
|
],
|
|
'Test connector.update: invalid "status" (not in range)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'status' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/status": value must be one of '.
|
|
implode(', ', [ZBX_CONNECTOR_STATUS_DISABLED, ZBX_CONNECTOR_STATUS_ENABLED]).'.'
|
|
],
|
|
|
|
// Check "tags_evaltype".
|
|
'Test connector.update: invalid "tags_evaltype" (string)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'tags_evaltype' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags_evaltype": an integer is expected.'
|
|
],
|
|
'Test connector.update: invalid "tags_evaltype" (not in range)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'tags_evaltype' => self::INVALID_NUMBER
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags_evaltype": value must be one of '.
|
|
implode(', ', [CONDITION_EVAL_TYPE_AND_OR, CONDITION_EVAL_TYPE_OR]).'.'
|
|
],
|
|
|
|
// Check "tags".
|
|
'Test connector.update: invalid "tags" (string)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'tags' => 'abc'
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags": an array is expected.'
|
|
],
|
|
'Test connector.update: invalid "tags" (array with string)' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'tags' => ['abc']
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1": an array is expected.'
|
|
],
|
|
'Test connector.update: missing "tag" for "tags"' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'tags' => [
|
|
[]
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1": the parameter "tag" is missing.'
|
|
],
|
|
'Test connector.update: unexpected parameter for "tags"' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'tags' => [
|
|
['abc' => '']
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1": unexpected parameter "abc".'
|
|
],
|
|
'Test connector.update: invalid "tag" (boolean) for "tags"' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'tags' => [
|
|
['tag' => false]
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/tag": a character string is expected.'
|
|
],
|
|
'Test connector.update: invalid "tag" (empty string) for "tags"' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'tags' => [
|
|
['tag' => '']
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/tag": cannot be empty.'
|
|
],
|
|
'Test connector.update: invalid "tag" (too long) for "tags"' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'tags' => [
|
|
['tag' => str_repeat('a', DB::getFieldLength('connector_tag', 'tag') + 1)]
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/tag": value is too long.'
|
|
],
|
|
'Test connector.update: invalid "operator" (boolean) for "tags"' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'tags' => [
|
|
['tag' => 'abc', 'operator' => false]
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/operator": an integer is expected.'
|
|
],
|
|
'Test connector.update: invalid "operator" (not in range) for "tags"' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'tags' => [
|
|
['tag' => 'abc', 'operator' => self::INVALID_NUMBER]
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/operator": value must be one of '.
|
|
implode(', ', [CONDITION_OPERATOR_EQUAL, CONDITION_OPERATOR_NOT_EQUAL, CONDITION_OPERATOR_LIKE,
|
|
CONDITION_OPERATOR_NOT_LIKE, CONDITION_OPERATOR_EXISTS, CONDITION_OPERATOR_NOT_EXISTS
|
|
]).'.'
|
|
],
|
|
'Test connector.update: invalid "value" (boolean) for "tags"' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'tags' => [
|
|
['tag' => 'abc', 'operator' => CONDITION_OPERATOR_EQUAL, 'value' => false]
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/value": a character string is expected.'
|
|
],
|
|
'Test connector.update: invalid "value" (not empty) for "tags"' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'tags' => [
|
|
['tag' => 'abc', 'operator' => CONDITION_OPERATOR_EXISTS, 'value' => '123']
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/value": value must be empty.'
|
|
],
|
|
'Test connector.update: invalid "value" (not empty) for "tags" 2' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'tags' => [
|
|
['tag' => 'abc', 'operator' => CONDITION_OPERATOR_NOT_EXISTS, 'value' => '123']
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/value": value must be empty.'
|
|
],
|
|
'Test connector.update: invalid "value" (too long) for "tags"' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'tags' => [
|
|
[
|
|
'tag' => 'abc',
|
|
'operator' => CONDITION_OPERATOR_EQUAL,
|
|
'value' => str_repeat('a', DB::getFieldLength('connector_tag', 'value') + 1)
|
|
]
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/1/value": value is too long.'
|
|
],
|
|
'Test connector.update: invalid "tag" (duplicate) for "tags"' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults',
|
|
'tags' => [
|
|
['tag' => 'abc', 'operator' => CONDITION_OPERATOR_EQUAL, 'value' => '123'],
|
|
['tag' => 'abc', 'operator' => CONDITION_OPERATOR_EQUAL, 'value' => '123']
|
|
]
|
|
],
|
|
'expected_error' => 'Invalid parameter "/1/tags/2": value (tag, operator, value)=(abc, 0, 123) already exists.'
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Data provider for connector.update. Array contains valid connector parameters.
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function getConnectorUpdateDataValid(): array {
|
|
return [
|
|
'Test connector.update: update single connector without changes' => [
|
|
'connector' => [
|
|
'connectorid' => 'update_custom_defaults'
|
|
],
|
|
'expected_error' => null
|
|
],
|
|
'Test connector.update: update multiple connectors' => [
|
|
'connector' => [
|
|
[
|
|
'connectorid' => 'update_custom_defaults',
|
|
'name' => 'API test connector.update - first connector'
|
|
],
|
|
[
|
|
'connectorid' => 'update_authtype_basic',
|
|
'name' => 'API test connector.update - second connector'
|
|
]
|
|
],
|
|
'expected_error' => null
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Test connector.update method.
|
|
*
|
|
* @dataProvider getConnectorUpdateDataInvalid
|
|
* @dataProvider getConnectorUpdateDataValid
|
|
*/
|
|
public function testConnector_Update(array $connectors, ?string $expected_error): void {
|
|
// Accept single and multiple connectors just like API method. Work with multidimensional array in result.
|
|
if (!array_key_exists(0, $connectors)) {
|
|
$connectors = zbx_toArray($connectors);
|
|
}
|
|
|
|
// Replace ID placeholders with real IDs.
|
|
foreach ($connectors as &$connector) {
|
|
$connector = self::resolveIds($connector);
|
|
}
|
|
unset($connector);
|
|
|
|
$sql_connectors = 'SELECT NULL FROM connector';
|
|
$old_hash_connectors = CDBHelper::getHash($sql_connectors);
|
|
|
|
if ($expected_error === null) {
|
|
$connectorids = array_column($connectors, 'connectorid');
|
|
$db_connectors = $this->getConnectors($connectorids);
|
|
|
|
$this->call('connector.update', $connectors, $expected_error);
|
|
|
|
$connectors_upd = $this->getConnectors($connectorids);
|
|
|
|
// Compare records from DB before and after API call.
|
|
foreach ($connectors as $connector) {
|
|
$db_connector = $db_connectors[$connector['connectorid']];
|
|
$connector_upd = $connectors_upd[$connector['connectorid']];
|
|
|
|
// Required fields.
|
|
$this->assertNotEmpty($connector_upd['name']);
|
|
$this->assertNotEmpty($connector_upd['url']);
|
|
|
|
// Numeric fields.
|
|
foreach (['protocol', 'data_type', 'max_records', 'max_senders', 'max_attempts', 'authtype',
|
|
'verify_peer', 'verify_host', 'status', 'tags_evaltype'] as $field) {
|
|
if (array_key_exists($field, $connector)) {
|
|
$this->assertEquals($connector[$field], $connector_upd[$field]);
|
|
}
|
|
else {
|
|
$this->assertEquals($db_connector[$field], $connector_upd[$field]);
|
|
}
|
|
}
|
|
|
|
// Text fields.
|
|
foreach (['timeout', 'http_proxy', 'ssl_cert_file', 'ssl_key_file', 'ssl_key_password', 'description']
|
|
as $field) {
|
|
if (array_key_exists($field, $connector)) {
|
|
$this->assertSame($connector[$field], $connector_upd[$field]);
|
|
}
|
|
else {
|
|
$this->assertSame($db_connector[$field], $connector_upd[$field]);
|
|
}
|
|
}
|
|
|
|
if (in_array($connector_upd['authtype'], [ZBX_HTTP_AUTH_BASIC, ZBX_HTTP_AUTH_NTLM,
|
|
ZBX_HTTP_AUTH_KERBEROS, ZBX_HTTP_AUTH_DIGEST])) {
|
|
foreach (['username', 'password'] as $field) {
|
|
if (array_key_exists($field, $connector)) {
|
|
$this->assertSame($connector[$field], $connector_upd[$field]);
|
|
}
|
|
else {
|
|
$this->assertSame($db_connector[$field], $connector_upd[$field]);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$this->assertEmpty($connector_upd['username']);
|
|
$this->assertEmpty($connector_upd['password']);
|
|
}
|
|
|
|
if ($connector_upd['authtype'] == ZBX_HTTP_AUTH_BEARER) {
|
|
$this->assertNotEmpty($connector_upd['token']);
|
|
|
|
if (array_key_exists($field, $connector)) {
|
|
$this->assertSame($connector['token'], $connector_upd['token']);
|
|
}
|
|
else {
|
|
$this->assertSame($db_connector['token'], $connector_upd['token']);
|
|
}
|
|
}
|
|
else {
|
|
$this->assertEmpty($connector_upd['token']);
|
|
}
|
|
|
|
// Tags.
|
|
if (array_key_exists('tags', $connector)) {
|
|
if ($connector['tags']) {
|
|
$this->assertNotEmpty($connector_upd['tags']);
|
|
$this->assertEqualsCanonicalizing($connector['tags'], $connector_upd['tags']);
|
|
}
|
|
else {
|
|
$this->assertEmpty($connector_upd['tags']);
|
|
}
|
|
}
|
|
else {
|
|
$this->assertEqualsCanonicalizing($db_connector['tags'], $connector_upd['tags']);
|
|
}
|
|
}
|
|
|
|
// Restore connector original data after each test.
|
|
$this->call('connector.update', $db_connectors);
|
|
}
|
|
else {
|
|
// Call method and make sure it really returns the error.
|
|
$this->call('connector.update', $connectors, $expected_error);
|
|
|
|
// Make sure nothing has changed as well.
|
|
$this->assertSame($old_hash_connectors, CDBHelper::getHash($sql_connectors));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Data provider for connector.delete. Array contains invalid connectors that are not possible to delete.
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function getConnectorDeleteDataInvalid(): array {
|
|
return [
|
|
// Check connector IDs.
|
|
'Test connector.delete: empty ID' => [
|
|
'connectorids' => [''],
|
|
'expected_error' => 'Invalid parameter "/1": a number is expected.'
|
|
],
|
|
'Test connector.delete: non-existent ID' => [
|
|
'connectorids' => [self::INVALID_ID],
|
|
'expected_error' => 'No permissions to referred object or it does not exist!'
|
|
],
|
|
'Test connector.delete: with two same IDs' => [
|
|
'connectorids' => [0, 0],
|
|
'expected_error' => 'Invalid parameter "/2": value (0) already exists.'
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Data provider for connector.delete. Array contains valid connectors.
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function getConnectorDeleteDataValid(): array {
|
|
return [
|
|
'Test connector.delete: delete single connector' => [
|
|
'connector' => ['delete_single'],
|
|
'expected_error' => null
|
|
],
|
|
'Test connector.delete: delete multiple connectors' => [
|
|
'connector' => [
|
|
'delete_multiple_1',
|
|
'delete_multiple_2'
|
|
],
|
|
'expected_error' => null
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Test connector.delete method.
|
|
*
|
|
* @dataProvider getConnectorDeleteDataInvalid
|
|
* @dataProvider getConnectorDeleteDataValid
|
|
*/
|
|
public function testConnector_Delete(array $connectorids, ?string $expected_error): void {
|
|
// Replace ID placeholders with real IDs.
|
|
foreach ($connectorids as &$connectorid) {
|
|
if (self::isValidIdPlaceholder($connectorid)) {
|
|
$connectorid = self::$data['connectorids'][$connectorid];
|
|
}
|
|
}
|
|
unset($connectorid);
|
|
|
|
$sql_connectors = 'SELECT NULL FROM connector';
|
|
$old_hash_connectors = CDBHelper::getHash($sql_connectors);
|
|
|
|
$this->call('connector.delete', $connectorids, $expected_error);
|
|
|
|
if ($expected_error === null) {
|
|
$this->assertNotSame($old_hash_connectors, CDBHelper::getHash($sql_connectors));
|
|
$this->assertEquals(0, CDBHelper::getCount(
|
|
'SELECT c.connectorid FROM connector c WHERE '.dbConditionId('c.connectorid', $connectorids)
|
|
));
|
|
|
|
// connector.delete checks if given IDs exist, so they need to be removed from self::$data['connectorids']
|
|
foreach ($connectorids as $connectorid) {
|
|
$key = array_search($connectorid, self::$data['connectorids']);
|
|
|
|
if ($key !== false) {
|
|
unset(self::$data['connectorids'][$key]);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$this->assertSame($old_hash_connectors, CDBHelper::getHash($sql_connectors));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the original connectors before update.
|
|
*
|
|
* @param array $connectorids
|
|
*
|
|
* @return array
|
|
*/
|
|
private function getConnectors(array $connectorids): array {
|
|
$response = $this->call('connector.get', [
|
|
'output' => ['connectorid', 'name', 'protocol', 'data_type', 'url', 'max_records', 'max_senders',
|
|
'max_attempts', 'timeout', 'http_proxy', 'authtype', 'username', 'password', 'token', 'verify_peer',
|
|
'verify_host', 'ssl_cert_file', 'ssl_key_file', 'ssl_key_password', 'description', 'status',
|
|
'tags_evaltype'
|
|
],
|
|
'selectTags' => ['tag', 'operator', 'value'],
|
|
'connectorids' => $connectorids,
|
|
'preservekeys' => true
|
|
]);
|
|
|
|
return $response['result'];
|
|
}
|
|
|
|
/**
|
|
* Delete all created data after test.
|
|
*/
|
|
public static function clearData(): void {
|
|
// Delete connectors.
|
|
$connectorids = array_values(self::$data['connectorids']);
|
|
$connectorids = array_merge($connectorids, self::$data['created']);
|
|
CDataHelper::call('connector.delete', $connectorids);
|
|
}
|
|
|
|
/**
|
|
* Helper method to convert placeholders to real IDs.
|
|
*
|
|
* @param array $request
|
|
*
|
|
* @return array
|
|
*/
|
|
private static function resolveIds(array $request): array {
|
|
if (array_key_exists('connectorids', $request)) {
|
|
if (is_array($request['connectorids'])) {
|
|
foreach ($request['connectorids'] as &$id_placeholder) {
|
|
if (self::isValidIdPlaceholder($id_placeholder)) {
|
|
$id_placeholder = self::$data['connectorids'][$id_placeholder];
|
|
}
|
|
}
|
|
unset($id_placeholder);
|
|
}
|
|
elseif (self::isValidIdPlaceholder($request['connectorids'])) {
|
|
$request['connectorids'] = self::$data['connectorids'][$request['connectorids']];
|
|
}
|
|
}
|
|
elseif (array_key_exists('connectorid', $request) && self::isValidIdPlaceholder($request['connectorid'])) {
|
|
$request['connectorid'] = self::$data['connectorids'][$request['connectorid']];
|
|
}
|
|
|
|
return $request;
|
|
}
|
|
|
|
/**
|
|
* Helper method to check ID placeholder.
|
|
*
|
|
* @param $id_placeholder
|
|
*
|
|
* @return bool
|
|
*/
|
|
private static function isValidIdPlaceholder($id_placeholder): bool {
|
|
// Do not compare != 0 (it will not work) or !== 0 or !== '0' (avoid type check here).
|
|
return !is_array($id_placeholder) && $id_placeholder != '0' && $id_placeholder !== ''
|
|
&& $id_placeholder !== null && $id_placeholder != self::INVALID_ID;
|
|
}
|
|
}
|