Merge branch 'collectd-5.8'
[collectd.git] / src / daemon / utils_subst_test.c
1 /**
2  * collectd - src/daemon/utils_subst_test.c
3  * Copyright (C) 2015       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 #include "common.h" /* for STATIC_ARRAY_SIZE */
29
30 #include "testing.h"
31 #include "utils_subst.h"
32
33 #if HAVE_KSTAT_H
34 #include <kstat.h>
35 #endif
36
37 #if HAVE_LIBKSTAT
38 kstat_ctl_t *kc;
39 #endif /* HAVE_LIBKSTAT */
40
41 DEF_TEST(subst) {
42   struct {
43     const char *str;
44     int off1;
45     int off2;
46     const char *rplmt;
47     const char *want;
48   } cases[] = {
49       {"foo_____bar", 3, 8, " - ", "foo - bar"}, /* documentation example */
50       {"foo bar", 0, 2, "m", "mo bar"},          /* beginning, shorten */
51       {"foo bar", 0, 1, "m", "moo bar"},         /* beginning, same length */
52       {"foo bar", 0, 3, "milk", "milk bar"},     /* beginning, extend */
53       {"foo bar", 3, 6, "de", "fooder"},         /* center, shorten */
54       {"foo bar", 2, 6, "rste", "forster"},      /* center, same length */
55       {"foo bar", 1, 3, "ish", "fish bar"},      /* center, extend */
56       {"foo bar", 2, 7, "ul", "foul"},           /* end, shorten */
57       {"foo bar", 3, 7, "lish", "foolish"},      /* end, same length */
58       {"foo bar", 3, 7, "dwear", "foodwear"},    /* end, extend */
59       /* truncation (buffer is 16 chars) */
60       {"01234567890123", 8, 8, "", "01234567890123"},
61       {"01234567890123", 8, 8, "*", "01234567*890123"},
62       {"01234567890123", 8, 8, "**", "01234567**89012"},
63       /* input > buffer */
64       {"012345678901234----", 0, 0, "", "012345678901234"},
65       {"012345678901234----", 17, 18, "", "012345678901234"},
66       {"012345678901234----", 0, 3, "", "345678901234---"},
67       {"012345678901234----", 0, 4, "", "45678901234----"},
68       {"012345678901234----", 0, 5, "", "5678901234----"},
69       {"012345678901234----", 8, 8, "#", "01234567#890123"},
70       {"012345678901234----", 12, 12, "##", "012345678901##2"},
71       {"012345678901234----", 13, 13, "##", "0123456789012##"},
72       {"012345678901234----", 14, 14, "##", "01234567890123#"},
73       {"012345678901234----", 15, 15, "##", "012345678901234"},
74       {"012345678901234----", 16, 16, "##", "012345678901234"},
75       /* error cases */
76       {NULL, 3, 4, "_", NULL},        /* no input */
77       {"foo bar", 3, 10, "_", NULL},  /* offset exceeds input */
78       {"foo bar", 10, 13, "_", NULL}, /* offset exceeds input */
79       {"foo bar", 4, 3, "_", NULL},   /* off1 > off2 */
80       {"foo bar", 3, 4, NULL, NULL},  /* no replacement */
81   };
82
83   for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) {
84     char buffer[16] = "!!!!!!!!!!!!!!!";
85
86     if (cases[i].want == NULL) {
87       OK(subst(buffer, sizeof(buffer), cases[i].str, cases[i].off1,
88                cases[i].off2, cases[i].rplmt) == NULL);
89       continue;
90     }
91
92     OK(subst(buffer, sizeof(buffer), cases[i].str, cases[i].off1, cases[i].off2,
93              cases[i].rplmt) == &buffer[0]);
94     EXPECT_EQ_STR(cases[i].want, buffer);
95   }
96
97   return 0;
98 }
99
100 DEF_TEST(subst_string) {
101   struct {
102     const char *str;
103     const char *srch;
104     const char *rplmt;
105     const char *want;
106   } cases[] = {
107       {"Hello %{name}", "%{name}", "world", "Hello world"},
108       {"abcccccc", "abc", "cab", "ccccccab"},
109       {"(((()(())))())", "()", "", ""},
110       {"food booth", "oo", "ee", "feed beeth"},
111       {"foo bar", "baz", "qux", "foo bar"},
112       {"foo bar", "oo", "oo", "foo bar"},
113       {"sixteen chars", "chars", "characters", "sixteen charact"},
114   };
115
116   for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) {
117     char buffer[16];
118
119     if (cases[i].want == NULL) {
120       OK(subst_string(buffer, sizeof(buffer), cases[i].str, cases[i].srch,
121                       cases[i].rplmt) == NULL);
122       continue;
123     }
124
125     OK(subst_string(buffer, sizeof(buffer), cases[i].str, cases[i].srch,
126                     cases[i].rplmt) == buffer);
127     EXPECT_EQ_STR(cases[i].want, buffer);
128   }
129
130   return 0;
131 }
132
133 int main(void) {
134   RUN_TEST(subst);
135   RUN_TEST(subst_string);
136
137   END_TEST;
138 }