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.
385 lines
12 KiB
385 lines
12 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 "zbxmocktest.h"
|
|
#include "zbxmockdata.h"
|
|
|
|
#include "zbxstr.h"
|
|
#include "zbxnum.h"
|
|
#include "cfg.h"
|
|
|
|
void zbx_mock_test_entry(void **state)
|
|
{
|
|
zbx_mock_error_t error;
|
|
zbx_mock_handle_t handle, parameters, parameter;
|
|
const char *cfg_file, *validation, *tmp, **multi_string, *string_list;
|
|
int strict = 42, exit_code, parameter_count = 0, i;
|
|
struct cfg_line *cfg = NULL;
|
|
void **expected_values = NULL;
|
|
|
|
ZBX_UNUSED(state);
|
|
|
|
if (ZBX_MOCK_SUCCESS != (error = zbx_mock_in_parameter("configuration file", &handle)) ||
|
|
ZBX_MOCK_SUCCESS != (error = zbx_mock_string(handle, &cfg_file)))
|
|
{
|
|
fail_msg("Cannot get configuration file from test case data: %s", zbx_mock_error_string(error));
|
|
}
|
|
|
|
if (ZBX_MOCK_SUCCESS != (error = zbx_mock_in_parameter("validation", &handle)) ||
|
|
ZBX_MOCK_SUCCESS != (error = zbx_mock_string(handle, &validation)))
|
|
{
|
|
fail_msg("Cannot get validation mode from test case data: %s", zbx_mock_error_string(error));
|
|
}
|
|
|
|
if (0 == strcmp(validation, "not strict"))
|
|
strict = ZBX_CFG_NOT_STRICT;
|
|
else if (0 == strcmp(validation, "strict"))
|
|
strict = ZBX_CFG_STRICT;
|
|
else
|
|
fail_msg("Invalid validation mode \"%s\".", validation);
|
|
|
|
if (ZBX_MOCK_SUCCESS != (error = zbx_mock_in_parameter("parameters", ¶meters)))
|
|
fail_msg("Cannot get description of parameters from test case data: %s", zbx_mock_error_string(error));
|
|
|
|
while (ZBX_MOCK_SUCCESS == (error = zbx_mock_vector_element(parameters, ¶meter)))
|
|
{
|
|
cfg = zbx_realloc(cfg, (parameter_count + 1) * sizeof(struct cfg_line));
|
|
expected_values = zbx_realloc(expected_values, (parameter_count + 1) * sizeof(void *));
|
|
|
|
if (ZBX_MOCK_SUCCESS != (error = zbx_mock_object_member(parameter, "name", &handle)) ||
|
|
ZBX_MOCK_SUCCESS != (error = zbx_mock_string(handle, &tmp)))
|
|
{
|
|
fail_msg("Cannot get name of parameter #%d: %s", parameter_count + 1,
|
|
zbx_mock_error_string(error));
|
|
}
|
|
|
|
cfg[parameter_count].parameter = tmp;
|
|
|
|
if (ZBX_MOCK_SUCCESS != (error = zbx_mock_object_member(parameter, "type", &handle)) ||
|
|
ZBX_MOCK_SUCCESS != (error = zbx_mock_string(handle, &tmp)))
|
|
{
|
|
fail_msg("Cannot get type of parameter #%d: %s", parameter_count + 1,
|
|
zbx_mock_error_string(error));
|
|
}
|
|
|
|
if (0 == strcmp(tmp, "numeric"))
|
|
{
|
|
if (ZBX_MOCK_NO_SUCH_MEMBER == (error = zbx_mock_object_member(parameter, "expect", &handle)))
|
|
{
|
|
expected_values[parameter_count] = NULL;
|
|
}
|
|
else if (ZBX_MOCK_SUCCESS == error && ZBX_MOCK_SUCCESS == (error = zbx_mock_string(handle, &tmp)))
|
|
{
|
|
expected_values[parameter_count] = zbx_malloc(NULL, sizeof(zbx_uint64_t));
|
|
|
|
if (SUCCEED != zbx_is_uint64(tmp, expected_values[parameter_count]))
|
|
{
|
|
fail_msg("Expected value \"%s\" of parameter #%d is not numeric.", tmp,
|
|
parameter_count + 1);
|
|
}
|
|
}
|
|
else
|
|
break;
|
|
|
|
cfg[parameter_count].variable = zbx_malloc(NULL, sizeof(zbx_uint64_t));
|
|
*(zbx_uint64_t *)cfg[parameter_count].variable = (zbx_uint64_t)-1;
|
|
|
|
if (ZBX_MOCK_NO_SUCH_MEMBER == (error = zbx_mock_object_member(parameter, "min", &handle)))
|
|
{
|
|
cfg[parameter_count].min = 0;
|
|
}
|
|
else if (ZBX_MOCK_SUCCESS == error && ZBX_MOCK_SUCCESS == (error = zbx_mock_string(handle, &tmp)))
|
|
{
|
|
zbx_uint64_t min;
|
|
|
|
if (SUCCEED != zbx_is_uint64(tmp, &min))
|
|
{
|
|
fail_msg("Minimum allowed value \"%s\" of parameter #%d is not numeric.", tmp,
|
|
parameter_count + 1);
|
|
}
|
|
|
|
cfg[parameter_count].min = min;
|
|
}
|
|
else
|
|
break;
|
|
|
|
if (ZBX_MOCK_NO_SUCH_MEMBER == (error = zbx_mock_object_member(parameter, "max", &handle)))
|
|
{
|
|
cfg[parameter_count].max = 0;
|
|
}
|
|
else if (ZBX_MOCK_SUCCESS == error && ZBX_MOCK_SUCCESS == (error = zbx_mock_string(handle, &tmp)))
|
|
{
|
|
zbx_uint64_t max;
|
|
|
|
if (SUCCEED != zbx_is_uint64(tmp, &max))
|
|
{
|
|
fail_msg("Maximum allowed value \"%s\" of parameter #%d is not numeric.", tmp,
|
|
parameter_count + 1);
|
|
}
|
|
|
|
cfg[parameter_count].max = max;
|
|
}
|
|
else
|
|
break;
|
|
|
|
cfg[parameter_count].type = TYPE_UINT64; /* no separate treatment for TYPE_INT */
|
|
}
|
|
else if (0 == strcmp(tmp, "string"))
|
|
{
|
|
if (ZBX_MOCK_NO_SUCH_MEMBER == (error = zbx_mock_object_member(parameter, "expect", &handle)))
|
|
{
|
|
expected_values[parameter_count] = NULL;
|
|
}
|
|
else if (ZBX_MOCK_SUCCESS == error && ZBX_MOCK_SUCCESS == (error = zbx_mock_string(handle, &tmp)))
|
|
{
|
|
expected_values[parameter_count] = zbx_malloc(NULL, sizeof(char *));
|
|
*(const char **)expected_values[parameter_count] = tmp;
|
|
}
|
|
else
|
|
break;
|
|
|
|
cfg[parameter_count].variable = zbx_malloc(NULL, sizeof(char *));
|
|
*(char **)cfg[parameter_count].variable = NULL;
|
|
cfg[parameter_count].min = 0;
|
|
cfg[parameter_count].max = 0;
|
|
cfg[parameter_count].type = TYPE_STRING;
|
|
}
|
|
else if (0 == strcmp(tmp, "string list"))
|
|
{
|
|
expected_values[parameter_count] = zbx_malloc(NULL, sizeof(zbx_mock_handle_t));
|
|
|
|
if (ZBX_MOCK_NO_SUCH_MEMBER == (error = zbx_mock_object_member(parameter, "expect",
|
|
expected_values[parameter_count])))
|
|
{
|
|
fail_msg("Missing expected field for parameter #%d of string list type, use [] instead.",
|
|
parameter_count + 1);
|
|
}
|
|
|
|
if (ZBX_MOCK_SUCCESS != error)
|
|
break;
|
|
|
|
cfg[parameter_count].variable = zbx_malloc(NULL, sizeof(char *));
|
|
*(char **)cfg[parameter_count].variable = NULL;
|
|
cfg[parameter_count].min = 0;
|
|
cfg[parameter_count].max = 0;
|
|
cfg[parameter_count].type = TYPE_STRING_LIST;
|
|
}
|
|
else if (0 == strcmp(tmp, "multi string"))
|
|
{
|
|
expected_values[parameter_count] = zbx_malloc(NULL, sizeof(zbx_mock_handle_t));
|
|
|
|
if (ZBX_MOCK_NO_SUCH_MEMBER == (error = zbx_mock_object_member(parameter, "expect",
|
|
expected_values[parameter_count])))
|
|
{
|
|
fail_msg("Missing expected field for parameter #%d of multi string type, use [] instead.",
|
|
parameter_count + 1);
|
|
}
|
|
|
|
if (ZBX_MOCK_SUCCESS != error)
|
|
break;
|
|
|
|
cfg[parameter_count].variable = zbx_malloc(NULL, sizeof(char **));
|
|
*(char ***)cfg[parameter_count].variable = NULL;
|
|
zbx_strarr_init((char ***)cfg[parameter_count].variable);
|
|
cfg[parameter_count].min = 0;
|
|
cfg[parameter_count].max = 0;
|
|
cfg[parameter_count].type = TYPE_MULTISTRING;
|
|
}
|
|
else
|
|
fail_msg("Invalid type \"%s\" of parameter #%d.", tmp, parameter_count + 1);
|
|
|
|
if (ZBX_MOCK_SUCCESS != (error = zbx_mock_object_member(parameter, "mandatory", &handle)) ||
|
|
ZBX_MOCK_SUCCESS != (error = zbx_mock_string(handle, &tmp)))
|
|
{
|
|
fail_msg("Cannot get mandatory flag of parameter #%d: %s", parameter_count + 1,
|
|
zbx_mock_error_string(error));
|
|
}
|
|
|
|
if (0 == strcmp(tmp, "yes"))
|
|
cfg[parameter_count].mandatory = PARM_MAND;
|
|
else if (0 == strcmp(tmp, "no"))
|
|
cfg[parameter_count].mandatory = PARM_OPT;
|
|
else
|
|
fail_msg("Invalid mandatory flag \"%s\" of parameter #%d.", tmp, parameter_count + 1);
|
|
|
|
parameter_count++;
|
|
}
|
|
|
|
if (ZBX_MOCK_END_OF_VECTOR != error)
|
|
{
|
|
fail_msg("Cannot get description of parameter #%d from test case data: %s", parameter_count + 1,
|
|
zbx_mock_error_string(error));
|
|
}
|
|
|
|
cfg = zbx_realloc(cfg, (parameter_count + 1) * sizeof(struct cfg_line));
|
|
cfg[parameter_count].parameter = NULL;
|
|
|
|
zbx_init_library_cfg(ZBX_PROGRAM_TYPE_SERVER, cfg_file);
|
|
|
|
parse_cfg_file(cfg_file, cfg, ZBX_CFG_FILE_REQUIRED, strict, ZBX_CFG_EXIT_FAILURE);
|
|
|
|
if (ZBX_MOCK_NO_EXIT_CODE != (error = zbx_mock_exit_code(&exit_code)))
|
|
{
|
|
if (ZBX_MOCK_SUCCESS == error)
|
|
fail_msg("parse_cfg_file() was expected to call exit(%d), but has not.", exit_code);
|
|
else
|
|
fail_msg("Cannot get exit code from test case data: %s", zbx_mock_error_string(error));
|
|
}
|
|
|
|
for (i = 0; i < parameter_count; i++)
|
|
{
|
|
switch (cfg[i].type)
|
|
{
|
|
case TYPE_MULTISTRING:
|
|
multi_string = *(const char ***)cfg[i].variable;
|
|
while (ZBX_MOCK_SUCCESS == (error = zbx_mock_vector_element(
|
|
*(zbx_mock_handle_t *)expected_values[i], &handle)) &&
|
|
ZBX_MOCK_SUCCESS == (error = zbx_mock_string(handle, &tmp)))
|
|
{
|
|
if (NULL == *multi_string)
|
|
{
|
|
fail_msg("Values of multi string parameter \"%s\" ended while \"%s\""
|
|
" was expected.", cfg[i].parameter, tmp);
|
|
}
|
|
|
|
if (0 != strcmp(*multi_string, tmp))
|
|
{
|
|
fail_msg("Value \"%s\" of multi string parameter \"%s\""
|
|
" differs from expected \"%s\".", *multi_string,
|
|
cfg[i].parameter, tmp);
|
|
}
|
|
|
|
multi_string++;
|
|
}
|
|
if (ZBX_MOCK_END_OF_VECTOR != error)
|
|
{
|
|
fail_msg("Cannot get expected values of multi string parameter \"%s\": %s",
|
|
cfg[i].parameter, zbx_mock_error_string(error));
|
|
}
|
|
if (NULL != *multi_string)
|
|
{
|
|
fail_msg("Value of multi string parameter \"%s\" ends with unexpected \"%s\""
|
|
" (and maybe more).", cfg[i].parameter, *multi_string);
|
|
}
|
|
break;
|
|
case TYPE_STRING_LIST:
|
|
string_list = *(const char **)cfg[i].variable;
|
|
while (ZBX_MOCK_SUCCESS == (error = zbx_mock_vector_element(
|
|
*(zbx_mock_handle_t *)expected_values[i], &handle)) &&
|
|
ZBX_MOCK_SUCCESS == (error = zbx_mock_string(handle, &tmp)))
|
|
{
|
|
if ('\0' == *string_list)
|
|
{
|
|
fail_msg("Value of string list parameter \"%s\" ended when \"%s{,...}\""
|
|
" was expected.", cfg[i].parameter, tmp);
|
|
}
|
|
|
|
if (0 != strncmp(string_list, tmp, strlen(tmp)))
|
|
{
|
|
fail_msg("Value of string list parameter \"%s\" starting with \"%s\""
|
|
" differs from expected \"%s{,...}\".", cfg[i].parameter,
|
|
string_list, tmp);
|
|
}
|
|
|
|
string_list += strlen(tmp);
|
|
|
|
if (',' != *string_list)
|
|
{
|
|
if ('\0' != *string_list)
|
|
{
|
|
fail_msg("Value of string list parameter \"%s\" starting with"
|
|
" \"%s\" differs from expected.", cfg[i].parameter,
|
|
string_list);
|
|
}
|
|
}
|
|
else
|
|
string_list++;
|
|
}
|
|
if (ZBX_MOCK_END_OF_VECTOR != error)
|
|
{
|
|
fail_msg("Cannot get expected value of string list parameter \"%s\": %s",
|
|
cfg[i].parameter, zbx_mock_error_string(error));
|
|
}
|
|
if ('\0' != *string_list)
|
|
{
|
|
fail_msg("Values of string list parameter \"%s\" ends with unexpected \"%s\".",
|
|
cfg[i].parameter, string_list);
|
|
}
|
|
break;
|
|
case TYPE_STRING:
|
|
if (NULL == *(char **)cfg[i].variable && NULL != *(char **)expected_values[i])
|
|
{
|
|
fail_msg("No value of string parameter \"%s\" while expected \"%s\".",
|
|
cfg[i].parameter, *(char **)expected_values[i]);
|
|
}
|
|
else if (NULL != *(char **)cfg[i].variable && NULL == *(char **)expected_values[i])
|
|
{
|
|
fail_msg("Got value \"%s\" of string parameter \"%s\" none was expected.",
|
|
*(char **)cfg[i].variable, cfg[i].parameter);
|
|
}
|
|
else if (NULL != *(char **)cfg[i].variable && NULL != *(char **)expected_values[i] &&
|
|
0 != strcmp(*(char **)cfg[i].variable, *(char **)expected_values[i]))
|
|
{
|
|
fail_msg("Value \"%s\" of string parameter \"%s\" differs from expected \"%s\".",
|
|
*(char **)cfg[i].variable, cfg[i].parameter,
|
|
*(char **)expected_values[i]);
|
|
}
|
|
break;
|
|
case TYPE_UINT64:
|
|
if (*(zbx_uint64_t *)cfg[i].variable != *(zbx_uint64_t *)expected_values[i])
|
|
{
|
|
fail_msg("Value " ZBX_FS_UI64 " of numeric parameter \"%s\""
|
|
" differs from expected (" ZBX_FS_UI64 ").",
|
|
*(zbx_uint64_t *)cfg[i].variable, cfg[i].parameter,
|
|
*(zbx_uint64_t *)expected_values[i]);
|
|
}
|
|
break;
|
|
default:
|
|
fail_msg("Invalid type of parameter \"%s\" when doing validation.", cfg[i].parameter);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < parameter_count; i++)
|
|
{
|
|
switch (cfg[i].type)
|
|
{
|
|
case TYPE_MULTISTRING:
|
|
zbx_strarr_free((char ***)cfg[i].variable);
|
|
zbx_free(cfg[i].variable);
|
|
zbx_free(expected_values[i]);
|
|
break;
|
|
case TYPE_STRING_LIST:
|
|
case TYPE_STRING:
|
|
zbx_free(*(char **)cfg[i].variable);
|
|
zbx_free(cfg[i].variable);
|
|
zbx_free(expected_values[i]);
|
|
break;
|
|
case TYPE_UINT64:
|
|
zbx_free(cfg[i].variable);
|
|
zbx_free(expected_values[i]);
|
|
break;
|
|
default:
|
|
fail_msg("Invalid type of parameter \"%s\" when doing cleanup.", cfg[i].parameter);
|
|
}
|
|
}
|
|
|
|
zbx_free(expected_values);
|
|
zbx_free(cfg);
|
|
}
|