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.
833 lines
30 KiB
833 lines
30 KiB
/*
|
|
** 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 "zbxmockassert.h"
|
|
#include "zbxmockdata.h"
|
|
#include "zbxmockutil.h"
|
|
#include "valuecache_mock.h"
|
|
|
|
#include "zbxcachevalue.h"
|
|
#include "zbxnum.h"
|
|
#include "zbxlog.h"
|
|
#include "zbxmutexs.h"
|
|
#include "zbxshmem.h"
|
|
#include "zbxalgo.h"
|
|
#include "zbxhistory.h"
|
|
#include "history.h"
|
|
#include "zbxcacheconfig.h"
|
|
#include "zbx_dbversion_constants.h"
|
|
|
|
#include <setjmp.h>
|
|
#include <cmocka.h>
|
|
|
|
|
|
/*
|
|
* data source
|
|
*/
|
|
static zbx_vcmock_ds_t vc_ds;
|
|
static zbx_timespec_t vcmock_ts;
|
|
|
|
int __wrap_zbx_mutex_create(zbx_mutex_t *mutex, zbx_mutex_name_t name, char **error);
|
|
void __wrap_zbx_mutex_destroy(zbx_mutex_t *mutex);
|
|
int __wrap_zbx_shmem_create(zbx_shmem_info_t **info, zbx_uint64_t size, const char *descr, const char *param,
|
|
int allow_oom, char **error);
|
|
void __wrap_zbx_shmem_destroy(zbx_shmem_info_t *info);
|
|
void *__wrap___zbx_shmem_malloc(const char *file, int line, zbx_shmem_info_t *info, const void *old, size_t size);
|
|
void *__wrap___zbx_shmem_realloc(const char *file, int line, zbx_shmem_info_t *info, void *old, size_t size);
|
|
void __wrap___zbx_shmem_free(const char *file, int line, zbx_shmem_info_t *info, void *ptr);
|
|
void __wrap_zbx_shmem_dump_stats(int level, zbx_shmem_info_t *info);
|
|
int __wrap_zbx_history_get_values(zbx_uint64_t itemid, int value_type, int start, int count, int end,
|
|
zbx_vector_history_record_t *values);
|
|
int __wrap_zbx_history_add_values(const zbx_vector_ptr_t *history);
|
|
void __wrap_zbx_history_sql_init(zbx_history_iface_t *hist, unsigned char value_type);
|
|
int __wrap_zbx_history_elastic_init(zbx_history_iface_t *hist, unsigned char value_type, char **error);
|
|
void __wrap_zbx_elastic_version_extract(void);
|
|
int __wrap_zbx_elastic_version_get(void);
|
|
time_t __wrap_time(time_t *ptr);
|
|
void __wrap_zbx_timespec(zbx_timespec_t *ts);
|
|
|
|
void zbx_vc_set_mode(int mode);
|
|
|
|
/* comparison function to sort history record vector by timestamps in ascending order */
|
|
static int history_compare(const void *d1, const void *d2)
|
|
{
|
|
zbx_history_record_t *h1 = (zbx_history_record_t *)d1;
|
|
zbx_history_record_t *h2 = (zbx_history_record_t *)d2;
|
|
|
|
return zbx_timespec_compare(&h1->timestamp, &h2->timestamp);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: reads history value and timestamp from input data *
|
|
* *
|
|
* Parameters: hvalue - [IN] handle to the history record mapping *
|
|
* value_type - [IN] the value type of the history data *
|
|
* value - [OUT] the history value *
|
|
* ts - [OUT] the history value timestamp *
|
|
* *
|
|
******************************************************************************/
|
|
|
|
static void zbx_vcmock_read_history_value(zbx_mock_handle_t hvalue, unsigned char value_type,
|
|
zbx_history_value_t *value, zbx_timespec_t *ts)
|
|
{
|
|
const char *data;
|
|
zbx_mock_error_t err;
|
|
zbx_mock_handle_t handle;
|
|
|
|
handle = zbx_mock_get_object_member_handle(hvalue, "value");
|
|
if (ZBX_MOCK_SUCCESS != (err = zbx_mock_string_ex(handle, &data)))
|
|
fail_msg("Cannot read history value: %s", zbx_mock_error_string(err));
|
|
|
|
if (ITEM_VALUE_TYPE_LOG != value_type)
|
|
{
|
|
switch (value_type)
|
|
{
|
|
case ITEM_VALUE_TYPE_STR:
|
|
case ITEM_VALUE_TYPE_TEXT:
|
|
value->str = zbx_strdup(NULL, data);
|
|
break;
|
|
case ITEM_VALUE_TYPE_UINT64:
|
|
if (FAIL == zbx_is_uint64(data, &value->ui64))
|
|
fail_msg("Invalid uint64 value \"%s\"", data);
|
|
break;
|
|
case ITEM_VALUE_TYPE_FLOAT:
|
|
value->dbl = atof(data);
|
|
break;
|
|
case ITEM_VALUE_TYPE_BIN:
|
|
break;
|
|
case ITEM_VALUE_TYPE_NONE:
|
|
default:
|
|
fail_msg("Unexpected value type: %c", value_type);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
zbx_log_value_t *log;
|
|
|
|
log = (zbx_log_value_t *)zbx_malloc(NULL, sizeof(zbx_log_value_t));
|
|
|
|
log->value = zbx_strdup(NULL, data);
|
|
log->source = zbx_strdup(NULL, zbx_mock_get_object_member_string(hvalue, "source"));
|
|
|
|
data = zbx_mock_get_object_member_string(hvalue, "logeventid");
|
|
if (FAIL == zbx_is_uint32(data, &log->logeventid))
|
|
fail_msg("Invalid log logeventid value \"%s\"", data);
|
|
|
|
data = zbx_mock_get_object_member_string(hvalue, "severity");
|
|
if (FAIL == zbx_is_uint32(data, &log->severity))
|
|
fail_msg("Invalid log severity value \"%s\"", data);
|
|
|
|
data = zbx_mock_get_object_member_string(hvalue, "timestamp");
|
|
if (FAIL == zbx_is_uint32(data, &log->timestamp))
|
|
fail_msg("Invalid log timestamp value \"%s\"", data);
|
|
|
|
value->log = log;
|
|
}
|
|
|
|
data = zbx_mock_get_object_member_string(hvalue, "ts");
|
|
if (ZBX_MOCK_SUCCESS != (err = zbx_strtime_to_timespec(data, ts)))
|
|
fail_msg("Invalid value timestamp \"%s\": %s", data, zbx_mock_error_string(err));
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: reads value cache data store item *
|
|
* *
|
|
* Parameters: hvalue - [IN] handle to the history record mapping *
|
|
* item - [OUT] the data store item *
|
|
* *
|
|
******************************************************************************/
|
|
static void zbx_vcmock_ds_read_item(zbx_mock_handle_t hitem, zbx_vcmock_ds_item_t *item)
|
|
{
|
|
const char *itemid;
|
|
|
|
itemid = zbx_mock_get_object_member_string(hitem, "itemid");
|
|
if (SUCCEED != zbx_is_uint64(itemid, &item->itemid))
|
|
fail_msg("Invalid itemid \"%s\"", itemid);
|
|
|
|
item->value_type = zbx_mock_str_to_value_type(zbx_mock_get_object_member_string(hitem, "value type"));
|
|
|
|
zbx_vector_history_record_create(&item->data);
|
|
zbx_vcmock_read_values(zbx_mock_get_object_member_handle(hitem, "data"), item->value_type, &item->data);
|
|
zbx_vector_history_record_sort(&item->data, history_compare);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: duplicates history record *
|
|
* *
|
|
* Parameters: src - [IN] source history record *
|
|
* value_type - [IN] the history record value type *
|
|
* dst - [OUT] the output record with duplicated data *
|
|
* *
|
|
******************************************************************************/
|
|
static void zbx_vcmock_ds_clone_record(const zbx_history_record_t *src, unsigned char value_type,
|
|
zbx_history_record_t *dst)
|
|
{
|
|
zbx_log_value_t *log;
|
|
|
|
dst->timestamp = src->timestamp;
|
|
|
|
switch (value_type)
|
|
{
|
|
case ITEM_VALUE_TYPE_FLOAT:
|
|
case ITEM_VALUE_TYPE_UINT64:
|
|
dst->value = src->value;
|
|
break;
|
|
case ITEM_VALUE_TYPE_STR:
|
|
case ITEM_VALUE_TYPE_TEXT:
|
|
dst->value.str = zbx_strdup(NULL, src->value.str);
|
|
break;
|
|
case ITEM_VALUE_TYPE_LOG:
|
|
log = (zbx_log_value_t *)zbx_malloc(NULL, sizeof(zbx_log_value_t));
|
|
log->value = zbx_strdup(NULL, src->value.log->value);
|
|
log->source = zbx_strdup(NULL, src->value.log->source);
|
|
log->logeventid = src->value.log->logeventid;
|
|
log->severity = src->value.log->severity;
|
|
log->timestamp = src->value.log->timestamp;
|
|
dst->value.log = log;
|
|
break;
|
|
case ITEM_VALUE_TYPE_BIN:
|
|
case ITEM_VALUE_TYPE_NONE:
|
|
default:
|
|
fail_msg("Unexpected value type: %c", value_type);
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: reads historical values from input data *
|
|
* *
|
|
* Parameters: hdata - [IN] handle to the history values in input data *
|
|
* value_type - [IN] the history record value type *
|
|
* values - [OUT] the read values *
|
|
* *
|
|
******************************************************************************/
|
|
void zbx_vcmock_read_values(zbx_mock_handle_t hdata, unsigned char value_type, zbx_vector_history_record_t *values)
|
|
{
|
|
zbx_mock_error_t err;
|
|
zbx_mock_handle_t hvalue;
|
|
zbx_history_record_t rec;
|
|
|
|
while (ZBX_MOCK_END_OF_VECTOR != (err = (zbx_mock_vector_element(hdata, &hvalue))))
|
|
{
|
|
zbx_vcmock_read_history_value(hvalue, value_type, &rec.value, &rec.timestamp);
|
|
zbx_vector_history_record_append_ptr(values, &rec);
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: initializes history data storage *
|
|
* *
|
|
* Comments: History data storage is used to emulate history storage backend. *
|
|
* *
|
|
******************************************************************************/
|
|
void zbx_vcmock_ds_init(void)
|
|
{
|
|
zbx_mock_handle_t hitems, hitem;
|
|
zbx_mock_error_t err;
|
|
int items_num = 0;
|
|
zbx_vcmock_ds_item_t item;
|
|
|
|
if (0 != setenv("TZ", "UTC", 1))
|
|
fail_msg("Cannot set 'TZ' environment variable: %s", zbx_strerror(errno));
|
|
|
|
tzset();
|
|
|
|
zbx_hashset_create(&vc_ds.items, 10, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
|
|
|
|
hitems = zbx_mock_get_parameter_handle("in.history");
|
|
|
|
while (ZBX_MOCK_END_OF_VECTOR != (err = (zbx_mock_vector_element(hitems, &hitem))))
|
|
{
|
|
if (ZBX_MOCK_SUCCESS != err)
|
|
fail_msg("Cannot read 'history' element #%d: %s", items_num, zbx_mock_error_string(err));
|
|
|
|
zbx_vcmock_ds_read_item(hitem, &item);
|
|
zbx_hashset_insert(&vc_ds.items, &item, sizeof(item));
|
|
|
|
items_num++;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: destroys history data storage *
|
|
* *
|
|
******************************************************************************/
|
|
void zbx_vcmock_ds_destroy(void)
|
|
{
|
|
zbx_hashset_iter_t iter;
|
|
zbx_vcmock_ds_item_t *item;
|
|
|
|
zbx_hashset_iter_reset(&vc_ds.items, &iter);
|
|
while (NULL != (item = zbx_hashset_iter_next(&iter)))
|
|
zbx_history_record_vector_destroy(&item->data, item->value_type);
|
|
|
|
zbx_hashset_destroy(&vc_ds.items);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: dumps history record vector contents to standard output *
|
|
* *
|
|
******************************************************************************/
|
|
static void zbx_vcmock_history_dump(unsigned char value_type, const zbx_vector_history_record_t *values)
|
|
{
|
|
int i;
|
|
char buffer[256];
|
|
|
|
for (i = 0; i < values->values_num; i++)
|
|
{
|
|
const zbx_history_record_t *rec = &values->values[i];
|
|
|
|
zbx_timespec_to_strtime(&rec->timestamp, buffer, sizeof(buffer));
|
|
printf(" - %s\n", buffer);
|
|
zbx_history_value2str(buffer, sizeof(buffer), &rec->value, value_type);
|
|
printf(" %s\n", buffer);
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: dumps history data store to standard output *
|
|
* *
|
|
******************************************************************************/
|
|
void zbx_vcmock_ds_dump(void)
|
|
{
|
|
zbx_hashset_iter_t iter;
|
|
zbx_vcmock_ds_item_t *item;
|
|
|
|
zbx_hashset_iter_reset((zbx_hashset_t *)&vc_ds.items, &iter);
|
|
while (NULL != (item = zbx_hashset_iter_next(&iter)))
|
|
{
|
|
printf("itemid:" ZBX_FS_UI64 ", value_type:%d\n", item->itemid, item->value_type);
|
|
zbx_vcmock_history_dump(item->value_type, &item->data);
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: returns first item in value cache mock data source *
|
|
* *
|
|
******************************************************************************/
|
|
zbx_vcmock_ds_item_t *zbx_vcmock_ds_first_item(void)
|
|
{
|
|
zbx_hashset_iter_t iter;
|
|
|
|
zbx_hashset_iter_reset((zbx_hashset_t *)&vc_ds.items, &iter);
|
|
return (zbx_vcmock_ds_item_t *)zbx_hashset_iter_next(&iter);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: converts value cache mode from text format *
|
|
* *
|
|
******************************************************************************/
|
|
int zbx_vcmock_str_to_cache_mode(const char *mode)
|
|
{
|
|
if (0 == strcmp(mode, "ZBX_VC_MODE_NORMAL"))
|
|
return ZBX_VC_MODE_NORMAL;
|
|
|
|
if (0 == strcmp(mode, "ZBX_VC_MODE_LOWMEM"))
|
|
return ZBX_VC_MODE_LOWMEM;
|
|
|
|
fail_msg("Unknown value cache mode \"%s\"", mode);
|
|
return FAIL;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: converts value cache item status from text format *
|
|
* *
|
|
******************************************************************************/
|
|
int zbx_vcmock_str_to_item_status(const char *str)
|
|
{
|
|
if (0 == strcmp(str, "ZBX_ITEM_STATUS_CACHED_ALL"))
|
|
return ZBX_ITEM_STATUS_CACHED_ALL;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: Compares two history record vectors and throw assertion if either *
|
|
* values or timestamps don't match *
|
|
* *
|
|
* Parameters: prefix - [IN] the assert message prefix *
|
|
* value_type - [IN] the value type *
|
|
* expected_values - [IN] the expected history records *
|
|
* returned_values - [IN] the returned history records *
|
|
* *
|
|
******************************************************************************/
|
|
void zbx_vcmock_check_records(const char *prefix, unsigned char value_type,
|
|
const zbx_vector_history_record_t *expected_values, const zbx_vector_history_record_t *returned_values)
|
|
{
|
|
int i;
|
|
const zbx_history_record_t *expected, *returned;
|
|
const zbx_log_value_t *expected_log, *returned_log;
|
|
|
|
printf("Expected values:\n");
|
|
zbx_vcmock_history_dump(value_type, expected_values);
|
|
|
|
printf("Returned values:\n");
|
|
zbx_vcmock_history_dump(value_type, returned_values);
|
|
|
|
zbx_mock_assert_int_eq(prefix, expected_values->values_num, returned_values->values_num);
|
|
|
|
for (i = 0; i < expected_values->values_num; i++)
|
|
{
|
|
expected = &expected_values->values[i];
|
|
returned = &returned_values->values[i];
|
|
|
|
zbx_mock_assert_timespec_eq(prefix, &expected->timestamp, &returned->timestamp);
|
|
|
|
switch (value_type)
|
|
{
|
|
case ITEM_VALUE_TYPE_STR:
|
|
case ITEM_VALUE_TYPE_TEXT:
|
|
zbx_mock_assert_str_eq(prefix, expected->value.str, returned->value.str);
|
|
break;
|
|
case ITEM_VALUE_TYPE_UINT64:
|
|
zbx_mock_assert_uint64_eq(prefix, expected->value.ui64, returned->value.ui64);
|
|
break;
|
|
case ITEM_VALUE_TYPE_LOG:
|
|
expected_log = expected->value.log;
|
|
returned_log = returned->value.log;
|
|
zbx_mock_assert_str_eq(prefix, expected_log->value, returned_log->value);
|
|
zbx_mock_assert_str_eq(prefix, expected_log->source, returned_log->source);
|
|
zbx_mock_assert_uint64_eq(prefix, expected_log->logeventid, returned_log->logeventid);
|
|
break;
|
|
case ITEM_VALUE_TYPE_FLOAT:
|
|
zbx_mock_assert_double_eq(prefix, expected->value.dbl, returned->value.dbl);
|
|
break;
|
|
case ITEM_VALUE_TYPE_BIN:
|
|
case ITEM_VALUE_TYPE_NONE:
|
|
default:
|
|
fail_msg("Unexpected value type: %c", value_type);
|
|
}
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: reads zbx_dc_history_t vector from input data *
|
|
* *
|
|
* Parameters: handle - [IN] the history data handle in input data *
|
|
* history - [OUT] the history records *
|
|
* *
|
|
******************************************************************************/
|
|
void zbx_vcmock_get_dc_history(zbx_mock_handle_t handle, zbx_vector_ptr_t *history)
|
|
{
|
|
zbx_mock_handle_t hitem, hdata;
|
|
zbx_mock_error_t err;
|
|
zbx_dc_history_t *data;
|
|
const char *itemid;
|
|
|
|
while (ZBX_MOCK_END_OF_VECTOR != (err = (zbx_mock_vector_element(handle, &hitem))))
|
|
{
|
|
if (ZBX_MOCK_SUCCESS != err)
|
|
{
|
|
fail_msg("Cannot read 'values' element #%d: %s", history->values_num,
|
|
zbx_mock_error_string(err));
|
|
}
|
|
|
|
data = (zbx_dc_history_t *)zbx_malloc(NULL, sizeof(zbx_dc_history_t));
|
|
memset(data, 0, sizeof(zbx_dc_history_t));
|
|
|
|
itemid = zbx_mock_get_object_member_string(hitem, "itemid");
|
|
if (SUCCEED != zbx_is_uint64(itemid, &data->itemid))
|
|
fail_msg("Invalid itemid \"%s\"", itemid);
|
|
|
|
data->value_type = zbx_mock_str_to_value_type(zbx_mock_get_object_member_string(hitem, "value type"));
|
|
hdata = zbx_mock_get_object_member_handle(hitem, "data");
|
|
zbx_vcmock_read_history_value(hdata, data->value_type, &data->value, &data->ts);
|
|
|
|
zbx_vector_ptr_append(history, data);
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: frees zbx_dc_history_t structure *
|
|
* *
|
|
******************************************************************************/
|
|
void zbx_vcmock_free_dc_history(void *ptr)
|
|
{
|
|
zbx_dc_history_t *h = (zbx_dc_history_t *)ptr;
|
|
|
|
switch (h->value_type)
|
|
{
|
|
case ITEM_VALUE_TYPE_STR:
|
|
case ITEM_VALUE_TYPE_TEXT:
|
|
zbx_free(h->value.str);
|
|
break;
|
|
case ITEM_VALUE_TYPE_LOG:
|
|
zbx_free(h->value.log->source);
|
|
zbx_free(h->value.log->value);
|
|
zbx_free(h->value.log);
|
|
break;
|
|
case ITEM_VALUE_TYPE_UINT64:
|
|
case ITEM_VALUE_TYPE_FLOAT:
|
|
break;
|
|
case ITEM_VALUE_TYPE_BIN:
|
|
case ITEM_VALUE_TYPE_NONE:
|
|
default:
|
|
fail_msg("Unexpected value type: %c", h->value_type);
|
|
}
|
|
|
|
zbx_free(h);
|
|
}
|
|
|
|
/*
|
|
* mock functions
|
|
*/
|
|
|
|
static zbx_mutex_t *vc_mutex = NULL;
|
|
zbx_shmem_info_t *vc_meminfo = NULL;
|
|
|
|
static size_t vcmock_mem = ZBX_MEBIBYTE * 1024;
|
|
|
|
int __wrap_zbx_mutex_create(zbx_mutex_t *mutex, zbx_mutex_name_t name, char **error)
|
|
{
|
|
vc_mutex = mutex;
|
|
ZBX_UNUSED(name);
|
|
ZBX_UNUSED(error);
|
|
|
|
return SUCCEED;
|
|
}
|
|
|
|
void __wrap_zbx_mutex_destroy(zbx_mutex_t *mutex)
|
|
{
|
|
zbx_mock_assert_ptr_eq("Attempting to destroy unknown mutex", vc_mutex, mutex);
|
|
}
|
|
|
|
int __wrap_zbx_shmem_create(zbx_shmem_info_t **info, zbx_uint64_t size, const char *descr, const char *param,
|
|
int allow_oom, char **error)
|
|
{
|
|
*info = vc_meminfo;
|
|
ZBX_UNUSED(size);
|
|
ZBX_UNUSED(descr);
|
|
ZBX_UNUSED(param);
|
|
ZBX_UNUSED(allow_oom);
|
|
ZBX_UNUSED(error);
|
|
|
|
return SUCCEED;
|
|
}
|
|
|
|
void __wrap_zbx_shmem_destroy(zbx_shmem_info_t *info)
|
|
{
|
|
zbx_free(info);
|
|
}
|
|
|
|
void *__wrap___zbx_shmem_malloc(const char *file, int line, zbx_shmem_info_t *info, const void *old, size_t size)
|
|
{
|
|
size_t *psize;
|
|
|
|
ZBX_UNUSED(file);
|
|
ZBX_UNUSED(line);
|
|
|
|
zbx_mock_assert_ptr_eq("Unknown memory info block in memory allocator", vc_meminfo, info);
|
|
zbx_mock_assert_ptr_eq("Allocating unfreed memory", NULL, old);
|
|
|
|
if (vcmock_mem < size)
|
|
return NULL;
|
|
|
|
psize = (size_t *)zbx_malloc(NULL, size + sizeof(size_t));
|
|
vcmock_mem -= size;
|
|
*psize = size;
|
|
|
|
return (void *)(psize + 1);
|
|
}
|
|
|
|
void *__wrap___zbx_shmem_realloc(const char *file, int line, zbx_shmem_info_t *info, void *old, size_t size)
|
|
{
|
|
size_t *psize;
|
|
|
|
ZBX_UNUSED(file);
|
|
ZBX_UNUSED(line);
|
|
|
|
zbx_mock_assert_ptr_eq("Unknown memory info block in memory reallocator", vc_meminfo, info);
|
|
|
|
psize = (size_t *)((char *)old - sizeof(size_t));
|
|
|
|
if (vcmock_mem + *psize < size)
|
|
return NULL;
|
|
|
|
psize = (size_t *)zbx_realloc(psize, size + sizeof(size_t));
|
|
vcmock_mem -= size;
|
|
*psize = size;
|
|
|
|
return (void *)(psize + 1);
|
|
}
|
|
|
|
void __wrap___zbx_shmem_free(const char *file, int line, zbx_shmem_info_t *info, void *ptr)
|
|
{
|
|
size_t *psize;
|
|
|
|
ZBX_UNUSED(file);
|
|
ZBX_UNUSED(line);
|
|
|
|
zbx_mock_assert_ptr_eq("Unknown memory info block in memory destructor", vc_meminfo, info);
|
|
|
|
if (NULL == ptr)
|
|
return;
|
|
|
|
psize = (size_t *)((char *)ptr - sizeof(size_t));
|
|
|
|
vcmock_mem += *psize;
|
|
|
|
zbx_free(psize);
|
|
}
|
|
|
|
void __wrap_zbx_shmem_dump_stats(int level, zbx_shmem_info_t *info)
|
|
{
|
|
ZBX_UNUSED(level);
|
|
ZBX_UNUSED(info);
|
|
}
|
|
|
|
int __wrap_zbx_history_get_values(zbx_uint64_t itemid, int value_type, int start, int count, int end,
|
|
zbx_vector_history_record_t *values)
|
|
{
|
|
zbx_vcmock_ds_item_t *item;
|
|
zbx_history_record_t *rec, rec_local;
|
|
int i;
|
|
|
|
if (0 > start)
|
|
fail_msg("invalid parameters passed to zbx_history_get_values function (start < 0)");
|
|
|
|
if (start >= end)
|
|
fail_msg("invalid parameters passed to zbx_history_get_values function (start >= end)");
|
|
|
|
if (NULL == (item = zbx_hashset_search(&vc_ds.items, &itemid)))
|
|
return SUCCEED;
|
|
|
|
if (0 == count)
|
|
count--;
|
|
|
|
for (i = item->data.values_num - 1; 0 <= i; i--)
|
|
{
|
|
rec = &item->data.values[i];
|
|
if (rec->timestamp.sec > end)
|
|
continue;
|
|
|
|
if (rec->timestamp.sec <= start || 0 == count--)
|
|
break;
|
|
|
|
zbx_vcmock_ds_clone_record(rec, value_type, &rec_local);
|
|
zbx_vector_history_record_append_ptr(values, &rec_local);
|
|
}
|
|
|
|
return SUCCEED;
|
|
}
|
|
|
|
int __wrap_zbx_history_add_values(const zbx_vector_ptr_t *history)
|
|
{
|
|
int i;
|
|
zbx_vcmock_ds_item_t *item, item_local;
|
|
zbx_history_record_t src, dst;
|
|
|
|
ZBX_UNUSED(history);
|
|
|
|
for (i = 0; i < history->values_num; i++)
|
|
{
|
|
const zbx_dc_history_t *h = (zbx_dc_history_t *)history->values[i];
|
|
|
|
if (NULL == (item = zbx_hashset_search(&vc_ds.items, &h->itemid)))
|
|
{
|
|
item_local.itemid = h->itemid;
|
|
item_local.value_type = h->value_type;
|
|
zbx_history_record_vector_create(&item_local.data);
|
|
|
|
item = zbx_hashset_insert(&vc_ds.items, &item_local, sizeof(item_local));
|
|
}
|
|
|
|
src.value = h->value;
|
|
src.timestamp = h->ts;
|
|
zbx_vcmock_ds_clone_record(&src, h->value_type, &dst);
|
|
zbx_vector_history_record_append_ptr(&item->data, &dst);
|
|
zbx_vector_history_record_sort(&item->data, history_compare);
|
|
}
|
|
|
|
return SUCCEED;
|
|
}
|
|
|
|
void __wrap_zbx_history_sql_init(zbx_history_iface_t *hist, unsigned char value_type)
|
|
{
|
|
ZBX_UNUSED(hist);
|
|
ZBX_UNUSED(value_type);
|
|
}
|
|
|
|
int __wrap_zbx_history_elastic_init(zbx_history_iface_t *hist, unsigned char value_type, char **error)
|
|
{
|
|
ZBX_UNUSED(hist);
|
|
ZBX_UNUSED(value_type);
|
|
ZBX_UNUSED(error);
|
|
|
|
return SUCCEED;
|
|
}
|
|
|
|
void __wrap_zbx_elastic_version_extract(void)
|
|
{
|
|
}
|
|
|
|
int __wrap_zbx_elastic_version_get(void)
|
|
{
|
|
return ZBX_DBVERSION_UNDEFINED;
|
|
}
|
|
|
|
/*
|
|
* cache allocator size limit handling
|
|
*/
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: sets the available memory for the wrapped memory allocator *
|
|
* *
|
|
******************************************************************************/
|
|
void zbx_vcmock_set_available_mem(size_t size)
|
|
{
|
|
vcmock_mem = size;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: retrieves the memory available in the wrapped memory allocator *
|
|
* *
|
|
******************************************************************************/
|
|
size_t zbx_vcmock_get_available_mem(void)
|
|
{
|
|
return vcmock_mem;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: sets the available size in value cache if the specified key is *
|
|
* present in input data *
|
|
* *
|
|
******************************************************************************/
|
|
void zbx_vcmock_set_cache_size(zbx_mock_handle_t hitem, const char *key)
|
|
{
|
|
const char *data;
|
|
zbx_mock_handle_t hmem;
|
|
zbx_uint64_t cache_size;
|
|
|
|
if (ZBX_MOCK_SUCCESS == zbx_mock_object_member(hitem, key, &hmem))
|
|
{
|
|
if (ZBX_MOCK_SUCCESS != zbx_mock_string(hmem, &data) || SUCCEED != zbx_is_uint64(data, &cache_size))
|
|
fail_msg("Cannot read \"%s\" parameter", key);
|
|
else
|
|
zbx_vcmock_set_available_mem(cache_size);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* input data parsing utility functions
|
|
*/
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: gets value cache precache or requests parameters from input data *
|
|
* *
|
|
******************************************************************************/
|
|
void zbx_vcmock_get_request_params(zbx_mock_handle_t handle, zbx_uint64_t *itemid, unsigned char *value_type,
|
|
int *seconds, int *count, zbx_timespec_t *end)
|
|
{
|
|
if (FAIL == zbx_is_uint64(zbx_mock_get_object_member_string(handle, "itemid"), itemid))
|
|
fail_msg("Invalid itemid value");
|
|
|
|
*value_type = zbx_mock_str_to_value_type(zbx_mock_get_object_member_string(handle, "value type"));
|
|
*seconds = atoi(zbx_mock_get_object_member_string(handle, "seconds"));
|
|
*count = atoi(zbx_mock_get_object_member_string(handle, "count"));
|
|
zbx_strtime_to_timespec(zbx_mock_get_object_member_string(handle, "end"), end);
|
|
}
|
|
|
|
/*
|
|
* cache working mode handling
|
|
*/
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: sets value cache mode if the specified key is present in input *
|
|
* data *
|
|
* *
|
|
******************************************************************************/
|
|
void zbx_vcmock_set_mode(zbx_mock_handle_t hitem, const char *key)
|
|
{
|
|
const char *data;
|
|
zbx_mock_handle_t hmode;
|
|
zbx_mock_error_t err;
|
|
|
|
if (ZBX_MOCK_SUCCESS == zbx_mock_object_member(hitem, key, &hmode))
|
|
{
|
|
if (ZBX_MOCK_SUCCESS != (err = zbx_mock_string(hmode, &data)))
|
|
fail_msg("Cannot read \"%s\" parameter: %s", key, zbx_mock_error_string(err));
|
|
|
|
zbx_vc_set_mode(zbx_vcmock_str_to_cache_mode(data));
|
|
}
|
|
}
|
|
|
|
/*
|
|
* time() emulation
|
|
*/
|
|
time_t __wrap_time(time_t *ptr)
|
|
{
|
|
if (NULL != ptr)
|
|
*ptr = vcmock_ts.sec;
|
|
|
|
return vcmock_ts.sec;
|
|
}
|
|
|
|
/*
|
|
* zbx_timespec() emulation
|
|
*/
|
|
void __wrap_zbx_timespec(zbx_timespec_t *ts)
|
|
{
|
|
*ts = vcmock_ts;
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: sets the current time. The key must be present in input data or *
|
|
* the test case will fail *
|
|
* *
|
|
******************************************************************************/
|
|
void zbx_vcmock_set_time(zbx_mock_handle_t hitem, const char *key)
|
|
{
|
|
zbx_mock_error_t err;
|
|
const char *data;
|
|
|
|
data = zbx_mock_get_object_member_string(hitem, key);
|
|
|
|
if (ZBX_MOCK_SUCCESS != (err = zbx_strtime_to_timespec(data, &vcmock_ts)))
|
|
fail_msg("Cannot read \"%s\" parameter", key);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* Purpose: returns the mocked current time *
|
|
* *
|
|
******************************************************************************/
|
|
zbx_timespec_t zbx_vcmock_get_ts(void)
|
|
{
|
|
return vcmock_ts;
|
|
}
|