/* ** 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 "zbxmockdb.h" #include "zbxnum.h" #include "zbxalgo.h" #include "zbxhistory.h" #include "zbxdb.h" #include "zbxdbhigh.h" #include "zbxavailability.h" void __wrap_zbx_sleep_loop(int sleeptime); zbx_uint64_t __wrap_zbx_dc_get_nextid(const char *table_name, int num); int __wrap_zbx_interface_availability_is_set(const zbx_interface_availability_t *ha); int __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 *error); int __wrap_zbx_process_events(zbx_vector_ptr_t *trigger_diff, zbx_vector_uint64_t *triggerids_lock); void __wrap_zbx_clean_events(void); void zbx_vcmock_read_values(zbx_mock_handle_t hdata, unsigned char value_type, zbx_vector_history_record_t *values); 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); void __wrap_zbx_recalc_time_period(time_t *ts_from, int table_group); void __wrap_zbx_sleep_loop(int sleeptime) { ZBX_UNUSED(sleeptime); } zbx_uint64_t __wrap_zbx_dc_get_nextid(const char *table_name, int num) { ZBX_UNUSED(table_name); ZBX_UNUSED(num); return 0; } int __wrap_zbx_interface_availability_is_set(const zbx_interface_availability_t *ha) { ZBX_UNUSED(ha); return SUCCEED; } int __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 *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(error); return SUCCEED; } 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 SUCCEED; } void __wrap_zbx_clean_events(void) { } void __wrap_zbx_recalc_time_period(time_t *ts_from, int table_group) { ZBX_UNUSED(ts_from); ZBX_UNUSED(table_group); } /****************************************************************************** * * * 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: 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; data = zbx_mock_get_object_member_string(hvalue, "value"); if (ITEM_VALUE_TYPE_LOG != value_type) { switch (value_type) { case ITEM_VALUE_TYPE_STR: case ITEM_VALUE_TYPE_TEXT: case ITEM_VALUE_TYPE_BIN: 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_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 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: 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: case ITEM_VALUE_TYPE_BIN: 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_NONE: default: fail_msg("Unexpected value type: %c", value_type); } } } /****************************************************************************** * * * Purpose: compares two cache values by their timestamps * * * * Parameters: d1 - [IN] the first value * * d2 - [IN] the second value * * * * Return value: >0 - the first value timestamp is less than second * * =0 - the first value timestamp is equal to the second * * <0 - the first value timestamp is greater than second * * * * Comments: This function is commonly used to sort value vector in descending* * order. * * * ******************************************************************************/ static int vc_history_record_compare_desc_func(const zbx_history_record_t *d1, const zbx_history_record_t *d2) { if (d1->timestamp.sec == d2->timestamp.sec) return d2->timestamp.ns - d1->timestamp.ns; return d2->timestamp.sec - d1->timestamp.sec; } void zbx_mock_test_entry(void **state) { char *error = NULL; int err, start, end, count, value_type, seconds; zbx_uint64_t itemid; zbx_timespec_t ts; zbx_vector_history_record_t values_received, values_expected; ZBX_UNUSED(state); zbx_mockdb_init(); err = zbx_history_init(&error); zbx_mock_assert_result_eq("zbx_history_init()", SUCCEED, err); if (FAIL == zbx_is_uint64(zbx_mock_get_parameter_string("in.itemid"), &itemid)) fail_msg("Invalid itemid value"); zbx_strtime_to_timespec(zbx_mock_get_parameter_string("in.end"), &ts); end = ts.sec; seconds = atoi(zbx_mock_get_parameter_string("in.seconds")); start = (0 == seconds ? 0 : end - seconds); count = atoi(zbx_mock_get_parameter_string("in.count")); value_type = zbx_mock_str_to_value_type(zbx_mock_get_parameter_string("in['value type']")); zbx_history_record_vector_create(&values_received); zbx_history_record_vector_create(&values_expected); err = zbx_history_get_values(itemid, value_type, start, count, end, &values_received); zbx_mock_assert_result_eq("zbx_history_get_values()", SUCCEED, err); zbx_vector_history_record_sort(&values_received, (zbx_compare_func_t)vc_history_record_compare_desc_func); zbx_vcmock_read_values(zbx_mock_get_parameter_handle("out.values"), value_type, &values_expected); zbx_vcmock_check_records("Returned values", value_type, &values_expected, &values_received); zbx_history_record_vector_destroy(&values_expected, value_type); zbx_history_record_vector_destroy(&values_received, value_type); zbx_history_destroy(); zbx_mockdb_destroy(); }