From 7535ee83bf0b12a168cee3c70e5fb97ed6dfc96c Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Sun, 5 Jun 2016 21:43:56 +0200 Subject: [PATCH] utils_cmds_test: Add various unit tests for the command parser. --- src/Makefile.am | 14 ++ src/daemon/plugin_mock.c | 15 ++ src/daemon/utils_cache_mock.c | 12 ++ src/testing.h | 5 +- src/utils_cmds_test.c | 252 ++++++++++++++++++++++++++++++++++ 5 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 src/utils_cmds_test.c diff --git a/src/Makefile.am b/src/Makefile.am index c545227f..d1249928 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -49,6 +49,20 @@ TESTS += test_utils_latency test_utils_latency_SOURCES = utils_latency_test.c testing.h test_utils_latency_LDADD = liblatency.la daemon/libplugin_mock.la -lm +noinst_LTLIBRARIES += libcmds.la +libcmds_la_SOURCES = utils_cmds.c utils_cmds.h \ + utils_cmd_flush.c utils_cmd_flush.h \ + utils_cmd_getval.c utils_cmd_getval.h \ + utils_cmd_listval.c utils_cmd_listval.h \ + utils_cmd_putval.c utils_cmd_putval.h \ + utils_parse_option.c +libcmds_la_LIBADD = daemon/libcommon.la daemon/libplugin_mock.la daemon/libmetadata.la +check_PROGRAMS += test_utils_cmds +TESTS += test_utils_cmds +test_utils_cmds_SOURCES = utils_cmds_test.c testing.h +test_utils_cmds_LDADD = libcmds.la \ + daemon/libplugin_mock.la daemon/libmetadata.la + noinst_LTLIBRARIES += liblookup.la liblookup_la_SOURCES = utils_vl_lookup.c utils_vl_lookup.h liblookup_la_LIBADD = daemon/libavltree.la diff --git a/src/daemon/plugin_mock.c b/src/daemon/plugin_mock.c index b6efa3ad..e01e2569 100644 --- a/src/daemon/plugin_mock.c +++ b/src/daemon/plugin_mock.c @@ -57,6 +57,21 @@ int plugin_dispatch_values (value_list_t const *vl) return ENOTSUP; } +int plugin_flush (const char *plugin, cdtime_t timeout, const char *identifier) +{ + return ENOTSUP; +} + +static data_source_t magic_ds[] = {{ "value", DS_TYPE_DERIVE, 0.0, NAN }}; +static data_set_t magic = { "MAGIC", 1, magic_ds }; +const data_set_t *plugin_get_ds (const char *name) +{ + if (strcmp (name, "MAGIC")) + return NULL; + + return &magic; +} + void plugin_log (int level, char const *format, ...) { char buffer[1024]; diff --git a/src/daemon/utils_cache_mock.c b/src/daemon/utils_cache_mock.c index 1080c806..3a14d043 100644 --- a/src/daemon/utils_cache_mock.c +++ b/src/daemon/utils_cache_mock.c @@ -25,9 +25,21 @@ */ #include "utils_cache.h" +#include gauge_t *uc_get_rate (__attribute__((unused)) data_set_t const *ds, __attribute__((unused)) value_list_t const *vl) { + errno = ENOTSUP; return (NULL); } + +int uc_get_rate_by_name (const char *name, gauge_t **ret_values, size_t *ret_values_num) +{ + return (ENOTSUP); +} + +int uc_get_names (char ***ret_names, cdtime_t **ret_times, size_t *ret_number) +{ + return (ENOTSUP); +} diff --git a/src/testing.h b/src/testing.h index 1bcc276c..1bc966c8 100644 --- a/src/testing.h +++ b/src/testing.h @@ -48,9 +48,12 @@ static int check_count__ = 0; #define END_TEST exit ((fail_count__ == 0) ? 0 : 1); +#define LOG(result, text) \ + printf ("%s %i - %s\n", result ? "ok" : "not ok", ++check_count__, text) + #define OK1(cond, text) do { \ _Bool result = (cond); \ - printf ("%s %i - %s\n", result ? "ok" : "not ok", ++check_count__, text); \ + LOG (result, text); \ if (!result) { return -1; } \ } while (0) #define OK(cond) OK1(cond, #cond) diff --git a/src/utils_cmds_test.c b/src/utils_cmds_test.c new file mode 100644 index 00000000..68b51403 --- /dev/null +++ b/src/utils_cmds_test.c @@ -0,0 +1,252 @@ +/** + * collectd - src/tests/utils_cmds_test.c + * Copyright (C) 2016 Sebastian 'tokkee' Harl + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Sebastian 'tokkee' Harl + **/ + +#include "common.h" +#include "testing.h" +#include "utils_cmds.h" + +static void error_cb (void *ud, cmd_status_t status, + const char *format, va_list ap) +{ + if (status == CMD_OK) + return; + + printf ("ERROR[%d]: ", status); + vprintf (format, ap); + printf ("\n"); + fflush (stdout); +} /* void error_cb */ + +struct { + char *input; + cmd_status_t expected_status; + cmd_type_t expected_type; +} parse_data[] = { + /* Valid FLUSH commands. */ + { + "FLUSH", + CMD_OK, + CMD_FLUSH, + }, + { + "FLUSH identifier=myhost/magic/MAGIC", + CMD_OK, + CMD_FLUSH, + }, + { + "FLUSH timeout=123 plugin=\"A\"", + CMD_OK, + CMD_FLUSH, + }, + /* Invalid FLUSH commands. */ + { + /* Missing 'identifier' key. */ + "FLUSH myhost/magic/MAGIC", + CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + { + /* Invalid timeout. */ + "FLUSH timeout=A", + CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + { + /* Invalid identifier. */ + "FLUSH identifier=invalid", + CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + { + /* Invalid option. */ + "FLUSH invalid=option", + CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + + /* Valid GETVAL commands. */ + { + "GETVAL myhost/magic/MAGIC", + CMD_OK, + CMD_GETVAL, + }, + + /* Invalid GETVAL commands. */ + { + "GETVAL", + CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + { + "GETVAL invalid", + CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + + /* Valid LISTVAL commands. */ + { + "LISTVAL", + CMD_OK, + CMD_LISTVAL, + }, + + /* Invalid LISTVAL commands. */ + { + "LISTVAL invalid", + CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + + /* Valid PUTVAL commands. */ + { + "PUTVAL myhost/magic/MAGIC N:42", + CMD_OK, + CMD_PUTVAL, + }, + { + "PUTVAL myhost/magic/MAGIC 1234:42", + CMD_OK, + CMD_PUTVAL, + }, + { + "PUTVAL myhost/magic/MAGIC 1234:42 2345:23", + CMD_OK, + CMD_PUTVAL, + }, + { + "PUTVAL myhost/magic/MAGIC interval=2 1234:42", + CMD_OK, + CMD_PUTVAL, + }, + { + "PUTVAL myhost/magic/MAGIC interval=2 1234:42 interval=5 2345:23", + CMD_OK, + CMD_PUTVAL, + }, + + /* Invalid PUTVAL commands. */ + { + "PUTVAL", + CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + { + "PUTVAL invalid N:42", + CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + { + "PUTVAL myhost/magic/MAGIC A:42", + CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + { + "PUTVAL myhost/magic/MAGIC 1234:A", + CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + { + "PUTVAL myhost/magic/MAGIC", + CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + { + "PUTVAL 1234:A", + CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + { + "PUTVAL myhost/magic/UNKNOWN 1234:42", + CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + /* + * As of collectd 5.x, PUTVAL accepts invalid options. + { + "PUTVAL myhost/magic/MAGIC invalid=2 1234:42", + CMD_PARSE_ERROR, + CMD_UNKNOWN, + }, + */ + + /* Invalid commands. */ + { + "INVALID", + CMD_UNKNOWN_COMMAND, + CMD_UNKNOWN, + }, + { + "INVALID interval=2", + CMD_UNKNOWN_COMMAND, + CMD_UNKNOWN, + }, +}; + +DEF_TEST(parse) +{ + cmd_error_handler_t err = { error_cb, NULL }; + int test_result = 0; + size_t i; + + for (i = 0; i < STATIC_ARRAY_SIZE (parse_data); i++) { + char *input = strdup (parse_data[i].input); + + char description[1024]; + cmd_status_t status; + cmd_t cmd; + + _Bool result; + + memset (&cmd, 0, sizeof (cmd)); + + status = cmd_parse (input, &cmd, &err); + snprintf (description, sizeof (description), + "cmd_parse (\"%s\") = %d (type=%d [%s]); want %d (type=%d [%s])", + parse_data[i].input, status, + cmd.type, CMD_TO_STRING (cmd.type), + parse_data[i].expected_status, + parse_data[i].expected_type, + CMD_TO_STRING (parse_data[i].expected_type)); + result = (status == parse_data[i].expected_status) + && (cmd.type == parse_data[i].expected_type); + LOG (result, description); + + /* Run all tests before failing. */ + if (! result) + test_result = -1; + + cmd_destroy (&cmd); + free (input); + } + + return (test_result); +} + +int main (int argc, char **argv) +{ + RUN_TEST(parse); + END_TEST; +} -- 2.30.2