X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fdaemon%2Fcommon_test.c;h=61435959bc4fe82e7faf7ebf34362e2859cc17b9;hb=1159cb5d383c55a80a0db100b8f7aadcf44740a5;hp=39ea5774d6ab68ef0623bd2c6dfacd2104d877e0;hpb=abc30f241619b3eb66c801c324390e1e9e6e001f;p=collectd.git diff --git a/src/daemon/common_test.c b/src/daemon/common_test.c index 39ea5774..4d2ccaa3 100644 --- a/src/daemon/common_test.c +++ b/src/daemon/common_test.c @@ -24,15 +24,14 @@ * Florian octo Forster */ -#include "testing.h" #include "common.h" +#include "testing.h" #if HAVE_LIBKSTAT kstat_ctl_t *kc; #endif /* HAVE_LIBKSTAT */ -DEF_TEST(sstrncpy) -{ +DEF_TEST(sstrncpy) { char buffer[16] = ""; char *ptr = &buffer[4]; char *ret; @@ -40,189 +39,215 @@ DEF_TEST(sstrncpy) buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0xff; buffer[12] = buffer[13] = buffer[14] = buffer[15] = 0xff; - ret = sstrncpy (ptr, "foobar", 8); + ret = sstrncpy(ptr, "foobar", 8); OK(ret == ptr); - STREQ ("foobar", ptr); + EXPECT_EQ_STR("foobar", ptr); OK(buffer[3] == buffer[12]); - ret = sstrncpy (ptr, "abc", 8); + ret = sstrncpy(ptr, "abc", 8); OK(ret == ptr); - STREQ ("abc", ptr); + EXPECT_EQ_STR("abc", ptr); OK(buffer[3] == buffer[12]); - ret = sstrncpy (ptr, "collectd", 8); + ret = sstrncpy(ptr, "collectd", 8); OK(ret == ptr); OK(ptr[7] == 0); - STREQ ("collect", ptr); + EXPECT_EQ_STR("collect", ptr); OK(buffer[3] == buffer[12]); - return (0); + return 0; } -DEF_TEST(ssnprintf) -{ - char buffer[16] = ""; - char *ptr = &buffer[4]; - int status; - - buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0xff; - buffer[12] = buffer[13] = buffer[14] = buffer[15] = 0xff; - - status = ssnprintf (ptr, 8, "%i", 1337); - OK(status == 4); - STREQ ("1337", ptr); - - status = ssnprintf (ptr, 8, "%s", "collectd"); - OK(status == 8); - OK(ptr[7] == 0); - STREQ ("collect", ptr); - OK(buffer[3] == buffer[12]); - - return (0); -} - -DEF_TEST(sstrdup) -{ +DEF_TEST(sstrdup) { char *ptr; - ptr = sstrdup ("collectd"); + ptr = sstrdup("collectd"); OK(ptr != NULL); - STREQ ("collectd", ptr); + EXPECT_EQ_STR("collectd", ptr); sfree(ptr); - OK(ptr == NULL); - ptr = sstrdup (NULL); + ptr = sstrdup(NULL); OK(ptr == NULL); - return (0); + return 0; } -DEF_TEST(strsplit) -{ +DEF_TEST(strsplit) { char buffer[32]; char *fields[8]; int status; - strncpy (buffer, "foo bar", sizeof (buffer)); - status = strsplit (buffer, fields, 8); + strncpy(buffer, "foo bar", sizeof(buffer)); + status = strsplit(buffer, fields, 8); OK(status == 2); - STREQ ("foo", fields[0]); - STREQ ("bar", fields[1]); + EXPECT_EQ_STR("foo", fields[0]); + EXPECT_EQ_STR("bar", fields[1]); - strncpy (buffer, "foo \t bar", sizeof (buffer)); - status = strsplit (buffer, fields, 8); + strncpy(buffer, "foo \t bar", sizeof(buffer)); + status = strsplit(buffer, fields, 8); OK(status == 2); - STREQ ("foo", fields[0]); - STREQ ("bar", fields[1]); + EXPECT_EQ_STR("foo", fields[0]); + EXPECT_EQ_STR("bar", fields[1]); - strncpy (buffer, "one two\tthree\rfour\nfive", sizeof (buffer)); - status = strsplit (buffer, fields, 8); + strncpy(buffer, "one two\tthree\rfour\nfive", sizeof(buffer)); + status = strsplit(buffer, fields, 8); OK(status == 5); - STREQ ("one", fields[0]); - STREQ ("two", fields[1]); - STREQ ("three", fields[2]); - STREQ ("four", fields[3]); - STREQ ("five", fields[4]); - - strncpy (buffer, "\twith trailing\n", sizeof (buffer)); - status = strsplit (buffer, fields, 8); + EXPECT_EQ_STR("one", fields[0]); + EXPECT_EQ_STR("two", fields[1]); + EXPECT_EQ_STR("three", fields[2]); + EXPECT_EQ_STR("four", fields[3]); + EXPECT_EQ_STR("five", fields[4]); + + strncpy(buffer, "\twith trailing\n", sizeof(buffer)); + status = strsplit(buffer, fields, 8); OK(status == 2); - STREQ ("with", fields[0]); - STREQ ("trailing", fields[1]); + EXPECT_EQ_STR("with", fields[0]); + EXPECT_EQ_STR("trailing", fields[1]); - strncpy (buffer, "1 2 3 4 5 6 7 8 9 10 11 12 13", sizeof (buffer)); - status = strsplit (buffer, fields, 8); + strncpy(buffer, "1 2 3 4 5 6 7 8 9 10 11 12 13", sizeof(buffer)); + status = strsplit(buffer, fields, 8); OK(status == 8); - STREQ ("7", fields[6]); - STREQ ("8", fields[7]); + EXPECT_EQ_STR("7", fields[6]); + EXPECT_EQ_STR("8", fields[7]); - strncpy (buffer, "single", sizeof (buffer)); - status = strsplit (buffer, fields, 8); + strncpy(buffer, "single", sizeof(buffer)); + status = strsplit(buffer, fields, 8); OK(status == 1); - STREQ ("single", fields[0]); + EXPECT_EQ_STR("single", fields[0]); - strncpy (buffer, "", sizeof (buffer)); - status = strsplit (buffer, fields, 8); + strncpy(buffer, "", sizeof(buffer)); + status = strsplit(buffer, fields, 8); OK(status == 0); - return (0); + return 0; } -DEF_TEST(strjoin) -{ - char buffer[16]; - char *fields[4]; - int status; - - fields[0] = "foo"; - fields[1] = "bar"; - fields[2] = "baz"; - fields[3] = "qux"; - - status = strjoin (buffer, sizeof (buffer), fields, 2, "!"); - OK(status == 7); - STREQ ("foo!bar", buffer); - - status = strjoin (buffer, sizeof (buffer), fields, 1, "!"); - OK(status == 3); - STREQ ("foo", buffer); - - status = strjoin (buffer, sizeof (buffer), fields, 0, "!"); - OK(status < 0); - - status = strjoin (buffer, sizeof (buffer), fields, 2, "rcht"); - OK(status == 10); - STREQ ("foorchtbar", buffer); - - status = strjoin (buffer, sizeof (buffer), fields, 4, ""); - OK(status == 12); - STREQ ("foobarbazqux", buffer); - - status = strjoin (buffer, sizeof (buffer), fields, 4, "!"); - OK(status == 15); - STREQ ("foo!bar!baz!qux", buffer); +DEF_TEST(strjoin) { + struct { + char **fields; + size_t fields_num; + char *separator; + + int want_return; + char *want_buffer; + } cases[] = { + /* Normal case. */ + {(char *[]){"foo", "bar"}, 2, "!", 7, "foo!bar"}, + /* One field only. */ + {(char *[]){"foo"}, 1, "!", 3, "foo"}, + /* No fields at all. */ + {NULL, 0, "!", 0, ""}, + /* Longer separator. */ + {(char *[]){"foo", "bar"}, 2, "rcht", 10, "foorchtbar"}, + /* Empty separator. */ + {(char *[]){"foo", "bar"}, 2, "", 6, "foobar"}, + /* NULL separator. */ + {(char *[]){"foo", "bar"}, 2, NULL, 6, "foobar"}, + /* buffer not large enough -> string is truncated. */ + {(char *[]){"aaaaaa", "bbbbbb", "c!"}, 3, "-", 16, "aaaaaa-bbbbbb-c"}, + /* buffer not large enough -> last field fills buffer completely. */ + {(char *[]){"aaaaaaa", "bbbbbbb", "!"}, 3, "-", 17, "aaaaaaa-bbbbbbb"}, + /* buffer not large enough -> string does *not* end in separator. */ + {(char *[]){"aaaa", "bbbb", "cccc", "!"}, 4, "-", 16, "aaaa-bbbb-cccc"}, + /* buffer not large enough -> string does not end with partial + separator. */ + {(char *[]){"aaaaaa", "bbbbbb", "!"}, 3, "+-", 17, "aaaaaa+-bbbbbb"}, + }; + + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { + char buffer[16]; + int status; + + memset(buffer, 0xFF, sizeof(buffer)); + status = strjoin(buffer, sizeof(buffer), cases[i].fields, + cases[i].fields_num, cases[i].separator); + EXPECT_EQ_INT(cases[i].want_return, status); + EXPECT_EQ_STR(cases[i].want_buffer, buffer); + } + + /* use (NULL, 0) to determine required buffer size. */ + EXPECT_EQ_INT(3, strjoin(NULL, 0, (char *[]){"a", "b"}, 2, "-")); + + return 0; +} - fields[0] = "0123"; - fields[1] = "4567"; - fields[2] = "8901"; - fields[3] = "2345"; - status = strjoin (buffer, sizeof (buffer), fields, 4, "-"); - OK(status < 0); +DEF_TEST(escape_slashes) { + struct { + char *str; + char *want; + } cases[] = { + {"foo/bar/baz", "foo_bar_baz"}, + {"/like/a/path", "like_a_path"}, + {"trailing/slash/", "trailing_slash_"}, + {"foo//bar", "foo__bar"}, + }; + + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { + char buffer[32]; + + strncpy(buffer, cases[i].str, sizeof(buffer)); + OK(escape_slashes(buffer, sizeof(buffer)) == 0); + EXPECT_EQ_STR(cases[i].want, buffer); + } + + return 0; +} - return (0); +DEF_TEST(escape_string) { + struct { + char *str; + char *want; + } cases[] = { + {"foobar", "foobar"}, + {"f00bar", "f00bar"}, + {"foo bar", "\"foo bar\""}, + {"foo \"bar\"", "\"foo \\\"bar\\\"\""}, + {"012345678901234", "012345678901234"}, + {"012345 78901234", "\"012345 789012\""}, + {"012345 78901\"34", "\"012345 78901\""}, + }; + + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { + char buffer[16]; + + strncpy(buffer, cases[i].str, sizeof(buffer)); + OK(escape_string(buffer, sizeof(buffer)) == 0); + EXPECT_EQ_STR(cases[i].want, buffer); + } + + return 0; } -DEF_TEST(strunescape) -{ +DEF_TEST(strunescape) { char buffer[16]; int status; - strncpy (buffer, "foo\\tbar", sizeof (buffer)); - status = strunescape (buffer, sizeof (buffer)); + strncpy(buffer, "foo\\tbar", sizeof(buffer)); + status = strunescape(buffer, sizeof(buffer)); OK(status == 0); - STREQ ("foo\tbar", buffer); + EXPECT_EQ_STR("foo\tbar", buffer); - strncpy (buffer, "\\tfoo\\r\\n", sizeof (buffer)); - status = strunescape (buffer, sizeof (buffer)); + strncpy(buffer, "\\tfoo\\r\\n", sizeof(buffer)); + status = strunescape(buffer, sizeof(buffer)); OK(status == 0); - STREQ ("\tfoo\r\n", buffer); + EXPECT_EQ_STR("\tfoo\r\n", buffer); - strncpy (buffer, "With \\\"quotes\\\"", sizeof (buffer)); - status = strunescape (buffer, sizeof (buffer)); + strncpy(buffer, "With \\\"quotes\\\"", sizeof(buffer)); + status = strunescape(buffer, sizeof(buffer)); OK(status == 0); - STREQ ("With \"quotes\"", buffer); + EXPECT_EQ_STR("With \"quotes\"", buffer); /* Backslash before null byte */ - strncpy (buffer, "\\tbackslash end\\", sizeof (buffer)); - status = strunescape (buffer, sizeof (buffer)); + strncpy(buffer, "\\tbackslash end\\", sizeof(buffer)); + status = strunescape(buffer, sizeof(buffer)); OK(status != 0); - STREQ ("\tbackslash end", buffer); - return (0); + EXPECT_EQ_STR("\tbackslash end", buffer); + return 0; /* Backslash at buffer end */ - strncpy (buffer, "\\t3\\56", sizeof (buffer)); - status = strunescape (buffer, 4); + strncpy(buffer, "\\t3\\56", sizeof(buffer)); + status = strunescape(buffer, 4); OK(status != 0); OK(buffer[0] == '\t'); OK(buffer[1] == '3'); @@ -232,19 +257,116 @@ DEF_TEST(strunescape) OK(buffer[5] == '6'); OK(buffer[6] == '7'); - return (0); + return 0; +} + +DEF_TEST(parse_values) { + struct { + char buffer[64]; + int status; + gauge_t value; + } cases[] = { + {"1435044576:42", 0, 42.0}, {"1435044576:42:23", -1, NAN}, + {"1435044576:U", 0, NAN}, {"N:12.3", 0, 12.3}, + {"N:42.0:23", -1, NAN}, {"N:U", 0, NAN}, + {"T:42.0", -1, NAN}, + }; + + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { + data_source_t dsrc = { + .name = "value", .type = DS_TYPE_GAUGE, .min = 0.0, .max = NAN, + }; + data_set_t ds = { + .type = "example", .ds_num = 1, .ds = &dsrc, + }; + + value_t v = { + .gauge = NAN, + }; + value_list_t vl = { + .values = &v, + .values_len = 1, + .time = 0, + .interval = 0, + .host = "example.com", + .plugin = "common_test", + .type = "example", + .meta = NULL, + }; + + int status = parse_values(cases[i].buffer, &vl, &ds); + EXPECT_EQ_INT(cases[i].status, status); + if (status != 0) + continue; + + EXPECT_EQ_DOUBLE(cases[i].value, vl.values[0].gauge); + } + + return 0; +} + +DEF_TEST(value_to_rate) { + struct { + time_t t0; + time_t t1; + int ds_type; + value_t v0; + value_t v1; + gauge_t want; + } cases[] = { + {0, 10, DS_TYPE_DERIVE, {.derive = 0}, {.derive = 1000}, NAN}, + {10, 20, DS_TYPE_DERIVE, {.derive = 1000}, {.derive = 2000}, 100.0}, + {20, 30, DS_TYPE_DERIVE, {.derive = 2000}, {.derive = 1800}, -20.0}, + {0, 10, DS_TYPE_COUNTER, {.counter = 0}, {.counter = 1000}, NAN}, + {10, 20, DS_TYPE_COUNTER, {.counter = 1000}, {.counter = 5000}, 400.0}, + /* 32bit wrap-around. */ + {20, + 30, + DS_TYPE_COUNTER, + {.counter = 4294967238ULL}, + {.counter = 42}, + 10.0}, + /* 64bit wrap-around. */ + {30, + 40, + DS_TYPE_COUNTER, + {.counter = 18446744073709551558ULL}, + {.counter = 42}, + 10.0}, + }; + + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { + cdtime_t t0 = TIME_T_TO_CDTIME_T(cases[i].t0); + value_to_rate_state_t state = { + .last_value = cases[i].v0, .last_time = t0, + }; + gauge_t got; + + if (cases[i].t0 == 0) { + EXPECT_EQ_INT(EAGAIN, + value_to_rate(&got, cases[i].v1, cases[i].ds_type, + TIME_T_TO_CDTIME_T(cases[i].t1), &state)); + continue; + } + + EXPECT_EQ_INT(0, value_to_rate(&got, cases[i].v1, cases[i].ds_type, + TIME_T_TO_CDTIME_T(cases[i].t1), &state)); + EXPECT_EQ_DOUBLE(cases[i].want, got); + } + + return 0; } -int main (void) -{ +int main(void) { RUN_TEST(sstrncpy); - RUN_TEST(ssnprintf); RUN_TEST(sstrdup); RUN_TEST(strsplit); RUN_TEST(strjoin); + RUN_TEST(escape_slashes); + RUN_TEST(escape_string); RUN_TEST(strunescape); + RUN_TEST(parse_values); + RUN_TEST(value_to_rate); END_TEST; } - -/* vim: set sw=2 sts=2 et : */