Merge branch 'collectd-5.7' into collectd-5.8
[collectd.git] / src / utils_format_graphite_test.c
1 /**
2  * collectd - src/utils_format_graphite_test.c
3  * Copyright (C) 2016       Florian octo Forster
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  *   Florian octo Forster <octo at collectd.org>
25  */
26
27 #include "collectd.h"
28
29 #include "common.h" /* for STATIC_ARRAY_SIZE */
30 #include "testing.h"
31 #include "utils_format_graphite.h"
32
33 static data_set_t ds_single = {
34     .type = "single",
35     .ds_num = 1,
36     .ds = &(data_source_t){"value", DS_TYPE_GAUGE, NAN, NAN},
37 };
38
39 /*
40 static data_set_t ds_double = {
41     .type = "double",
42     .ds_num = 2,
43     .ds =
44         (data_source_t[]){
45             {"one", DS_TYPE_DERIVE, 0, NAN}, {"two", DS_TYPE_DERIVE, 0, NAN},
46         },
47 };
48 */
49
50 DEF_TEST(metric_name) {
51   struct {
52     const char *plugin_instance;
53     const char *type_instance;
54     const char *prefix;
55     const char *suffix;
56     unsigned int flags;
57     const char *want_name;
58   } cases[] = {
59       {
60           .want_name = "example@com.test.single",
61       },
62       /* plugin and type instances */
63       {
64           .plugin_instance = "foo",
65           .type_instance = "bar",
66           .want_name = "example@com.test-foo.single-bar",
67       },
68       {
69           .plugin_instance = NULL,
70           .type_instance = "bar",
71           .want_name = "example@com.test.single-bar",
72       },
73       {
74           .plugin_instance = "foo",
75           .type_instance = NULL,
76           .want_name = "example@com.test-foo.single",
77       },
78       /* special chars */
79       {
80           .plugin_instance = "foo (test)",
81           .type_instance = "test: \"hello\"",
82           .want_name = "example@com.test-foo@@test@.single-test@@@hello@",
83       },
84       /* flag GRAPHITE_SEPARATE_INSTANCES */
85       {
86           .plugin_instance = "foo",
87           .type_instance = "bar",
88           .flags = GRAPHITE_SEPARATE_INSTANCES,
89           .want_name = "example@com.test.foo.single.bar",
90       },
91       /* flag GRAPHITE_ALWAYS_APPEND_DS */
92       {
93           .plugin_instance = "foo",
94           .type_instance = "bar",
95           .flags = GRAPHITE_ALWAYS_APPEND_DS,
96           .want_name = "example@com.test-foo.single-bar.value",
97       },
98       /* flag GRAPHITE_PRESERVE_SEPARATOR */
99       {
100           .plugin_instance = "f.o.o",
101           .type_instance = "b.a.r",
102           .flags = 0,
103           .want_name = "example@com.test-f@o@o.single-b@a@r",
104       },
105       {
106           .plugin_instance = "f.o.o",
107           .type_instance = "b.a.r",
108           .flags = GRAPHITE_PRESERVE_SEPARATOR,
109           .want_name = "example.com.test-f.o.o.single-b.a.r",
110       },
111       /* prefix and suffix */
112       {
113           .prefix = "foo.",
114           .suffix = ".bar",
115           .want_name = "foo.example@com.bar.test.single",
116       },
117       {
118           .prefix = NULL,
119           .suffix = ".bar",
120           .want_name = "example@com.bar.test.single",
121       },
122       {
123           .prefix = "foo.",
124           .suffix = NULL,
125           .want_name = "foo.example@com.test.single",
126       },
127   };
128
129   for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) {
130     value_list_t vl = {
131         .values = &(value_t){.gauge = 42},
132         .values_len = 1,
133         .time = TIME_T_TO_CDTIME_T_STATIC(1480063672),
134         .interval = TIME_T_TO_CDTIME_T_STATIC(10),
135         .host = "example.com",
136         .plugin = "test",
137         .type = "single",
138     };
139
140     char want[1024];
141     snprintf(want, sizeof(want), "%s 42 1480063672\r\n", cases[i].want_name);
142
143     if (cases[i].plugin_instance != NULL)
144       sstrncpy(vl.plugin_instance, cases[i].plugin_instance,
145                sizeof(vl.plugin_instance));
146     if (cases[i].type_instance != NULL)
147       sstrncpy(vl.type_instance, cases[i].type_instance,
148                sizeof(vl.type_instance));
149
150     char got[1024];
151     EXPECT_EQ_INT(0, format_graphite(got, sizeof(got), &ds_single, &vl,
152                                      cases[i].prefix, cases[i].suffix, '@',
153                                      cases[i].flags));
154     EXPECT_EQ_STR(want, got);
155   }
156
157   return 0;
158 }
159
160 DEF_TEST(null_termination) {
161   value_list_t vl = {
162       .values = &(value_t){.gauge = 1337},
163       .values_len = 1,
164       .time = TIME_T_TO_CDTIME_T_STATIC(1480063672),
165       .interval = TIME_T_TO_CDTIME_T_STATIC(10),
166       .host = "example.com",
167       .plugin = "test",
168       .type = "single",
169   };
170   char const *want = "example_com.test.single 1337 1480063672\r\n";
171
172   char buffer[128];
173   for (size_t i = 0; i < sizeof(buffer); i++)
174     buffer[i] = (char)i;
175
176   EXPECT_EQ_INT(0, format_graphite(buffer, sizeof(buffer), &ds_single, &vl,
177                                    NULL, NULL, '_', 0));
178   EXPECT_EQ_STR(want, buffer);
179   EXPECT_EQ_INT(0, buffer[strlen(want)]);
180   for (size_t i = strlen(want) + 1; i < sizeof(buffer); i++)
181     EXPECT_EQ_INT((int)i, (int)buffer[i]);
182
183   return 0;
184 }
185
186 int main(void) {
187   RUN_TEST(metric_name);
188   RUN_TEST(null_termination);
189
190   END_TEST;
191 }