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.
390 lines
13 KiB
390 lines
13 KiB
1 year ago
|
/*
|
||
|
** 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.
|
||
|
**/
|
||
|
|
||
|
#include "zbxmocktest.h"
|
||
|
#include "zbxmockdata.h"
|
||
|
#include "zbxmockassert.h"
|
||
|
#include "zbxmockutil.h"
|
||
|
#include "zbxalgo.h"
|
||
|
#include "zbxself.h"
|
||
|
#include "../../../src/zabbix_server/server.h"
|
||
|
|
||
|
#include "mock_service.h"
|
||
|
|
||
|
zbx_uint64_t __wrap_zbx_dc_get_nextid(const char *table_name, int num);
|
||
|
void *__wrap_zbx_add_event(unsigned char source, unsigned char object, zbx_uint64_t objectid,
|
||
|
const zbx_timespec_t *timespec, int value, const char *trigger_description,
|
||
|
const char *trigger_expression, const char *trigger_recovery_expression, unsigned char trigger_priority,
|
||
|
unsigned char trigger_type, const zbx_vector_ptr_t *trigger_tags,
|
||
|
unsigned char trigger_correlation_mode, const char *trigger_correlation_tag,
|
||
|
unsigned char trigger_value, const char *trigger_opdata, const char *event_name, const char *error);
|
||
|
int __wrap_zbx_process_events(zbx_vector_ptr_t *trigger_diff, zbx_vector_uint64_t *triggerids_lock);
|
||
|
void __wrap_zbx_clean_events(void);
|
||
|
int __wrap_zbx_interface_availability_is_set(const void *ia);
|
||
|
|
||
|
/* stubs to satisfy hard link dependenceies */
|
||
|
|
||
|
int get_process_info_by_thread(int local_server_num, unsigned char *local_process_type, int *local_process_num);
|
||
|
|
||
|
int CONFIG_SERVICEMAN_SYNC_FREQUENCY = 0;
|
||
|
|
||
|
pid_t *threads;
|
||
|
int threads_num;
|
||
|
|
||
|
void zbx_update_selfmon_counter(const zbx_thread_info_t *info, unsigned char state)
|
||
|
{
|
||
|
ZBX_UNUSED(state);
|
||
|
ZBX_UNUSED(info);
|
||
|
}
|
||
|
|
||
|
int get_process_info_by_thread(int local_server_num, unsigned char *local_process_type, int *local_process_num)
|
||
|
{
|
||
|
ZBX_UNUSED(local_server_num);
|
||
|
ZBX_UNUSED(local_process_type);
|
||
|
ZBX_UNUSED(local_process_num);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int MAIN_ZABBIX_ENTRY(int flags)
|
||
|
{
|
||
|
ZBX_UNUSED(flags);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/* service tree mock */
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
zbx_hashset_t services;
|
||
|
}
|
||
|
zbx_mock_service_cache_t;
|
||
|
|
||
|
static zbx_mock_service_cache_t cache;
|
||
|
|
||
|
static zbx_hash_t service_hash_func(const void *d)
|
||
|
{
|
||
|
const zbx_service_t *s = (const zbx_service_t *)d;
|
||
|
|
||
|
return ZBX_DEFAULT_STRING_HASH_FUNC(s->name);
|
||
|
}
|
||
|
|
||
|
static int service_compare_func(const void *d1, const void *d2)
|
||
|
{
|
||
|
const zbx_service_t *s1 = (const zbx_service_t *)d1;
|
||
|
const zbx_service_t *s2 = (const zbx_service_t *)d2;
|
||
|
|
||
|
return strcmp(s1->name, s2->name);
|
||
|
}
|
||
|
|
||
|
zbx_service_t *mock_get_service(const char *name)
|
||
|
{
|
||
|
zbx_service_t service_local;
|
||
|
|
||
|
service_local.name = (char *)name;
|
||
|
return zbx_hashset_search(&cache.services, &service_local);
|
||
|
}
|
||
|
|
||
|
void mock_init_service_cache(const char *path)
|
||
|
{
|
||
|
zbx_mock_handle_t hservices, hservice, hchildren, hparents, hname, hevents, hevent, halgo, hweight, hprop,
|
||
|
hrules, hrule;
|
||
|
int service_num = 0;
|
||
|
zbx_mock_error_t err;
|
||
|
zbx_service_t *service, service_local, *child, *parent;
|
||
|
const char *value;
|
||
|
zbx_hashset_iter_t iter;
|
||
|
|
||
|
zbx_hashset_create(&cache.services, 100, service_hash_func, service_compare_func);
|
||
|
|
||
|
/* load service objects in cache */
|
||
|
|
||
|
hservices = zbx_mock_get_parameter_handle(path);
|
||
|
while (ZBX_MOCK_END_OF_VECTOR != (err = (zbx_mock_vector_element(hservices, &hservice))))
|
||
|
{
|
||
|
if (ZBX_MOCK_SUCCESS != err)
|
||
|
fail_msg("cannot read service #%d", service_num);
|
||
|
|
||
|
memset(&service_local, 0, sizeof(zbx_service_t));
|
||
|
service_local.name = zbx_strdup(NULL, zbx_mock_get_object_member_string(hservice, "name"));
|
||
|
service = (zbx_service_t *)zbx_hashset_insert(&cache.services, &service_local, sizeof(service_local));
|
||
|
|
||
|
zbx_vector_ptr_create(&service->children);
|
||
|
zbx_vector_ptr_create(&service->parents);
|
||
|
zbx_vector_ptr_create(&service->service_problem_tags);
|
||
|
zbx_vector_ptr_create(&service->service_problems);
|
||
|
zbx_vector_ptr_create(&service->status_rules);
|
||
|
zbx_vector_ptr_create(&service->tags);
|
||
|
|
||
|
service->status = zbx_mock_get_object_member_int(hservice, "status");
|
||
|
|
||
|
if (ZBX_MOCK_SUCCESS == zbx_mock_object_member(hservice, "algorithm", &halgo))
|
||
|
{
|
||
|
if (ZBX_MOCK_SUCCESS != zbx_mock_string(halgo, &value))
|
||
|
fail_msg("cannot read service '%s' algorithm", service->name);
|
||
|
|
||
|
if (0 == strcmp(value, "MIN"))
|
||
|
service->algorithm = ZBX_SERVICE_STATUS_CALC_MOST_CRITICAL_ONE;
|
||
|
else if (0 == strcmp(value, "MAX"))
|
||
|
service->algorithm = ZBX_SERVICE_STATUS_CALC_MOST_CRITICAL_ALL;
|
||
|
else if (0 == strcmp(value, "OK"))
|
||
|
service->algorithm = ZBX_SERVICE_STATUS_CALC_SET_OK;
|
||
|
else
|
||
|
fail_msg("unknown service '%s' algorithm '%s'", service->name, value);
|
||
|
}
|
||
|
else
|
||
|
service->algorithm = ZBX_SERVICE_STATUS_CALC_MOST_CRITICAL_ONE;
|
||
|
|
||
|
if (ZBX_MOCK_SUCCESS == zbx_mock_object_member(hservice, "weight", &hweight))
|
||
|
{
|
||
|
if (ZBX_MOCK_SUCCESS != zbx_mock_int(hweight, &service->weight))
|
||
|
fail_msg("cannot read service '%s' weight", service->name);
|
||
|
}
|
||
|
|
||
|
if (ZBX_MOCK_SUCCESS == zbx_mock_object_member(hservice, "propagation", &hprop))
|
||
|
{
|
||
|
value = zbx_mock_get_object_member_string(hprop, "action");
|
||
|
|
||
|
if (0 == strcmp(value, "SET"))
|
||
|
{
|
||
|
service->propagation_rule = ZBX_SERVICE_STATUS_PROPAGATION_FIXED;
|
||
|
service->propagation_value = zbx_mock_get_object_member_int(hprop, "value");
|
||
|
}
|
||
|
else if (0 == strcmp(value, "KEEP"))
|
||
|
{
|
||
|
service->propagation_rule = ZBX_SERVICE_STATUS_PROPAGATION_AS_IS;
|
||
|
}
|
||
|
else if (0 == strcmp(value, "INCREASE"))
|
||
|
{
|
||
|
service->propagation_rule = ZBX_SERVICE_STATUS_PROPAGATION_INCREASE;
|
||
|
service->propagation_value = zbx_mock_get_object_member_int(hprop, "value");
|
||
|
}
|
||
|
else if (0 == strcmp(value, "DECREASE"))
|
||
|
{
|
||
|
service->propagation_rule = ZBX_SERVICE_STATUS_PROPAGATION_DECREASE;
|
||
|
service->propagation_value = zbx_mock_get_object_member_int(hprop, "value");
|
||
|
}
|
||
|
else if (0 == strcmp(value, "IGNORE"))
|
||
|
service->propagation_rule = ZBX_SERVICE_STATUS_PROPAGATION_IGNORE;
|
||
|
else
|
||
|
fail_msg("unknown service '%s' propagation action '%s'", service->name, value);
|
||
|
}
|
||
|
|
||
|
if (ZBX_MOCK_SUCCESS == zbx_mock_object_member(hservice, "rules", &hrules))
|
||
|
{
|
||
|
zbx_service_rule_t *rule;
|
||
|
|
||
|
while (ZBX_MOCK_END_OF_VECTOR != (err = (zbx_mock_vector_element(hrules, &hrule))))
|
||
|
{
|
||
|
if (ZBX_MOCK_SUCCESS != err)
|
||
|
fail_msg("cannot read service '%s' status rules", service->name);
|
||
|
|
||
|
rule = (zbx_service_rule_t *)zbx_malloc(NULL, sizeof(zbx_service_rule_t));
|
||
|
memset(rule, 0, sizeof(zbx_service_rule_t));
|
||
|
value = zbx_mock_get_object_member_string(hrule, "type");
|
||
|
if (0 == strcmp(value, "N_GE"))
|
||
|
rule->type = ZBX_SERVICE_STATUS_RULE_TYPE_N_GE;
|
||
|
else if (0 == strcmp(value, "NP_GE"))
|
||
|
rule->type = ZBX_SERVICE_STATUS_RULE_TYPE_NP_GE;
|
||
|
else if (0 == strcmp(value, "N_LT"))
|
||
|
rule->type = ZBX_SERVICE_STATUS_RULE_TYPE_N_L;
|
||
|
else if (0 == strcmp(value, "NP_LT"))
|
||
|
rule->type = ZBX_SERVICE_STATUS_RULE_TYPE_NP_L;
|
||
|
else if (0 == strcmp(value, "W_GE"))
|
||
|
rule->type = ZBX_SERVICE_STATUS_RULE_TYPE_W_GE;
|
||
|
else if (0 == strcmp(value, "WP_GE"))
|
||
|
rule->type = ZBX_SERVICE_STATUS_RULE_TYPE_WP_GE;
|
||
|
else if (0 == strcmp(value, "W_LT"))
|
||
|
rule->type = ZBX_SERVICE_STATUS_RULE_TYPE_W_L;
|
||
|
else if (0 == strcmp(value, "WP_LT"))
|
||
|
rule->type = ZBX_SERVICE_STATUS_RULE_TYPE_WP_L;
|
||
|
else
|
||
|
fail_msg("unsupported service '%s' rule type '%s'", service->name, value);
|
||
|
rule->limit_status = zbx_mock_get_object_member_int(hrule, "limit");
|
||
|
rule->limit_value = zbx_mock_get_object_member_int(hrule, "value");
|
||
|
rule->new_status = zbx_mock_get_object_member_int(hrule, "status");
|
||
|
zbx_vector_ptr_append(&service->status_rules, rule);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (ZBX_MOCK_SUCCESS == zbx_mock_object_member(hservice, "events", &hevents))
|
||
|
{
|
||
|
zbx_service_problem_t *problem;
|
||
|
|
||
|
while (ZBX_MOCK_END_OF_VECTOR != (err = (zbx_mock_vector_element(hevents, &hevent))))
|
||
|
{
|
||
|
if (ZBX_MOCK_SUCCESS != err)
|
||
|
fail_msg("cannot read service '%s' events", service->name);
|
||
|
|
||
|
problem = (zbx_service_problem_t *)zbx_malloc(NULL, sizeof(zbx_service_problem_t));
|
||
|
memset(problem, 0, sizeof(zbx_service_problem_t));
|
||
|
problem->eventid = zbx_mock_get_object_member_uint64(hevent, "id");
|
||
|
problem->severity = zbx_mock_get_object_member_int(hevent, "severity");
|
||
|
zbx_vector_ptr_append(&service->service_problems, problem);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
service_num++;
|
||
|
}
|
||
|
|
||
|
/* set service relations */
|
||
|
|
||
|
hservices = zbx_mock_get_parameter_handle(path);
|
||
|
while (ZBX_MOCK_END_OF_VECTOR != (err = (zbx_mock_vector_element(hservices, &hservice))))
|
||
|
{
|
||
|
if (ZBX_MOCK_SUCCESS != err)
|
||
|
fail_msg("cannot read service");
|
||
|
|
||
|
if (NULL == (service = mock_get_service(zbx_mock_get_object_member_string(hservice, "name"))))
|
||
|
fail_msg("failed to cache service '%s'", zbx_mock_get_object_member_string(hservice, "name"));
|
||
|
|
||
|
if (ZBX_MOCK_SUCCESS == zbx_mock_object_member(hservice, "children", &hchildren))
|
||
|
{
|
||
|
while (ZBX_MOCK_END_OF_VECTOR != (err = (zbx_mock_vector_element(hchildren, &hname))))
|
||
|
{
|
||
|
if (ZBX_MOCK_SUCCESS != err || ZBX_MOCK_SUCCESS != zbx_mock_string(hname, &value))
|
||
|
fail_msg("cannot read service '%s' children", service->name);
|
||
|
|
||
|
if (NULL == (child = mock_get_service(value)))
|
||
|
{
|
||
|
fail_msg("cannot set service '%s' child '%s': no such service", service->name,
|
||
|
value);
|
||
|
}
|
||
|
|
||
|
zbx_vector_ptr_append(&service->children, child);
|
||
|
zbx_vector_ptr_append(&child->parents, service);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (ZBX_MOCK_SUCCESS == zbx_mock_object_member(hservice, "parents", &hparents))
|
||
|
{
|
||
|
while (ZBX_MOCK_END_OF_VECTOR != (err = (zbx_mock_vector_element(hparents, &hname))))
|
||
|
{
|
||
|
if (ZBX_MOCK_SUCCESS != err || ZBX_MOCK_SUCCESS != zbx_mock_string(hname, &value))
|
||
|
fail_msg("cannot read service '%s' parents", service->name);
|
||
|
|
||
|
if (NULL == (parent = mock_get_service(value)))
|
||
|
{
|
||
|
fail_msg("cannot set service '%s' parent '%s': no such service", service->name,
|
||
|
value);
|
||
|
}
|
||
|
|
||
|
zbx_vector_ptr_append(&service->parents, parent);
|
||
|
zbx_vector_ptr_append(&parent->children, service);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
service_num++;
|
||
|
}
|
||
|
|
||
|
zbx_hashset_iter_reset(&cache.services, &iter);
|
||
|
|
||
|
/* remove duplicate parent/children references */
|
||
|
while (NULL != (service = (zbx_service_t *)zbx_hashset_iter_next(&iter)))
|
||
|
{
|
||
|
zbx_vector_ptr_sort(&service->parents, ZBX_DEFAULT_PTR_COMPARE_FUNC);
|
||
|
zbx_vector_ptr_uniq(&service->parents, ZBX_DEFAULT_PTR_COMPARE_FUNC);
|
||
|
|
||
|
zbx_vector_ptr_sort(&service->children, ZBX_DEFAULT_PTR_COMPARE_FUNC);
|
||
|
zbx_vector_ptr_uniq(&service->children, ZBX_DEFAULT_PTR_COMPARE_FUNC);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void mock_destroy_service_cache(void)
|
||
|
{
|
||
|
zbx_hashset_iter_t iter;
|
||
|
zbx_service_t *service;
|
||
|
|
||
|
zbx_hashset_iter_reset(&cache.services, &iter);
|
||
|
|
||
|
while (NULL != (service = (zbx_service_t *)zbx_hashset_iter_next(&iter)))
|
||
|
{
|
||
|
zbx_vector_ptr_destroy(&service->children);
|
||
|
zbx_vector_ptr_destroy(&service->parents);
|
||
|
zbx_vector_ptr_destroy(&service->service_problem_tags);
|
||
|
zbx_vector_ptr_destroy(&service->tags);
|
||
|
zbx_vector_ptr_clear_ext(&service->service_problems, zbx_ptr_free);
|
||
|
zbx_vector_ptr_destroy(&service->service_problems);
|
||
|
zbx_vector_ptr_clear_ext(&service->status_rules, zbx_ptr_free);
|
||
|
zbx_vector_ptr_destroy(&service->status_rules);
|
||
|
|
||
|
zbx_free(service->name);
|
||
|
}
|
||
|
|
||
|
zbx_hashset_destroy(&cache.services);
|
||
|
}
|
||
|
|
||
|
/* function stubs to cut off library dependencies */
|
||
|
|
||
|
zbx_uint64_t __wrap_zbx_dc_get_nextid(const char *table_name, int num)
|
||
|
{
|
||
|
ZBX_UNUSED(table_name);
|
||
|
ZBX_UNUSED(num);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void *__wrap_zbx_add_event(unsigned char source, unsigned char object, zbx_uint64_t objectid,
|
||
|
const zbx_timespec_t *timespec, int value, const char *trigger_description,
|
||
|
const char *trigger_expression, const char *trigger_recovery_expression, unsigned char trigger_priority,
|
||
|
unsigned char trigger_type, const zbx_vector_ptr_t *trigger_tags,
|
||
|
unsigned char trigger_correlation_mode, const char *trigger_correlation_tag,
|
||
|
unsigned char trigger_value, const char *trigger_opdata, const char *event_name, const char *error)
|
||
|
{
|
||
|
ZBX_UNUSED(source);
|
||
|
ZBX_UNUSED(object);
|
||
|
ZBX_UNUSED(objectid);
|
||
|
ZBX_UNUSED(timespec);
|
||
|
ZBX_UNUSED(value);
|
||
|
ZBX_UNUSED(trigger_description);
|
||
|
ZBX_UNUSED(trigger_expression);
|
||
|
ZBX_UNUSED(trigger_recovery_expression);
|
||
|
ZBX_UNUSED(trigger_priority);
|
||
|
ZBX_UNUSED(trigger_type);
|
||
|
ZBX_UNUSED(trigger_tags);
|
||
|
ZBX_UNUSED(trigger_correlation_mode);
|
||
|
ZBX_UNUSED(trigger_correlation_tag);
|
||
|
ZBX_UNUSED(trigger_value);
|
||
|
ZBX_UNUSED(trigger_opdata);
|
||
|
ZBX_UNUSED(event_name);
|
||
|
ZBX_UNUSED(error);
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
int __wrap_zbx_process_events(zbx_vector_ptr_t *trigger_diff, zbx_vector_uint64_t *triggerids_lock)
|
||
|
{
|
||
|
ZBX_UNUSED(trigger_diff);
|
||
|
ZBX_UNUSED(triggerids_lock);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void __wrap_zbx_clean_events(void)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
int __wrap_zbx_interface_availability_is_set(const void *ia)
|
||
|
{
|
||
|
ZBX_UNUSED(ia);
|
||
|
|
||
|
return FAIL;
|
||
|
}
|
||
|
|
||
|
|