1 /**
2 * collectd - src/ceph_test.c
3 * Copyright (C) 2015 Florian octo Forster
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; only version 2 of the License is applicable.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 * Authors:
19 * Florian octo Forster <octo at collectd.org>
20 **/
22 #include "ceph.c" /* sic */
23 #include "testing.h"
25 struct case_s
26 {
27 const char *key;
28 const char *value;
29 };
30 typedef struct case_s case_t;
32 struct test_s
33 {
34 case_t *cases;
35 size_t cases_num;
36 };
37 typedef struct test_s test_t;
39 static int test_handler(void *user, char const *val, char const *key)
40 {
41 test_t *t = user;
42 size_t i;
44 char status[1024];
45 _Bool ok;
47 /* special case for latency metrics. */
48 if (strcmp ("filestore.example_latency", key) == 0)
49 return RETRY_AVGCOUNT;
51 snprintf (status, sizeof (status), "unexpected call: test_handler(\"%s\") = \"%s\"", key, val);
52 ok = 0;
54 for (i = 0; i < t->cases_num; i++)
55 {
56 if (strcmp (key, t->cases[i].key) != 0)
57 continue;
59 if (strcmp (val, t->cases[i].value) != 0)
60 {
61 snprintf (status, sizeof (status), "test_handler(\"%s\") = \"%s\", want \"%s\"", key, val, t->cases[i].value);
62 ok = 0;
63 break;
64 }
66 snprintf (status, sizeof (status), "test_handler(\"%s\") = \"%s\"", key, val);
67 ok = 1;
68 break;
69 }
71 OK1(ok, status);
72 return ok ? 0 : -1;
73 }
75 DEF_TEST(traverse_json)
76 {
77 char const *json = "{\n"
78 " \"WBThrottle\": {\n"
79 " \"bytes_dirtied\": {\n"
80 " \"type\": 2,\n"
81 " \"description\": \"Dirty data\",\n"
82 " \"nick\": \"\"\n"
83 " },\n"
84 " \"bytes_wb\": {\n"
85 " \"type\": 2,\n"
86 " \"description\": \"Written data\",\n"
87 " \"nick\": \"\"\n"
88 " },\n"
89 " \"ios_dirtied\": {\n"
90 " \"type\": 2,\n"
91 " \"description\": \"Dirty operations\",\n"
92 " \"nick\": \"\"\n"
93 " },\n"
94 " \"ios_wb\": {\n"
95 " \"type\": 2,\n"
96 " \"description\": \"Written operations\",\n"
97 " \"nick\": \"\"\n"
98 " },\n"
99 " \"inodes_dirtied\": {\n"
100 " \"type\": 2,\n"
101 " \"description\": \"Entries waiting for write\",\n"
102 " \"nick\": \"\"\n"
103 " },\n"
104 " \"inodes_wb\": {\n"
105 " \"type\": 10,\n"
106 " \"description\": \"Written entries\",\n"
107 " \"nick\": \"\"\n"
108 " }\n"
109 " },\n"
110 " \"filestore\": {\n"
111 " \"journal_wr_bytes\": {\n"
112 " \"avgcount\": 23,\n"
113 " \"sum\": 3117\n"
114 " },\n"
115 " \"example_latency\": {\n"
116 " \"avgcount\": 42,\n"
117 " \"sum\": 4711\n"
118 " }\n"
119 " }\n"
120 "}\n";
121 case_t cases[] = {
122 {"WBThrottle.bytes_dirtied.type", "2"},
123 {"WBThrottle.bytes_wb.type", "2"},
124 {"WBThrottle.ios_dirtied.type", "2"},
125 {"WBThrottle.ios_wb.type", "2"},
126 {"WBThrottle.inodes_dirtied.type", "2"},
127 {"WBThrottle.inodes_wb.type", "10"},
128 {"filestore.journal_wr_bytes", "3117"},
129 {"filestore.example_latency.avgcount", "42"},
130 {"filestore.example_latency.sum", "4711"},
131 };
132 test_t t = {cases, STATIC_ARRAY_SIZE (cases)};
134 yajl_struct ctx = {test_handler, &t};
136 yajl_handle hndl;
137 #if HAVE_YAJL_V2
138 hndl = yajl_alloc (&callbacks, NULL, &ctx);
139 CHECK_ZERO (traverse_json ((const unsigned char *) json, (uint32_t) strlen (json), hndl));
140 CHECK_ZERO (yajl_complete_parse (hndl));
141 #else
142 hndl = yajl_alloc (&callbacks, NULL, NULL, &ctx);
143 CHECK_ZERO (traverse_json ((const unsigned char *) json, (uint32_t) strlen (json), hndl));
144 CHECK_ZERO (yajl_parse_complete (hndl));
145 #endif
147 return 0;
148 }
150 DEF_TEST(parse_keys)
151 {
152 struct {
153 const char *str;
154 const char *want;
155 } cases[] = {
156 {"WBThrottle.bytes_dirtied.description.bytes_wb.description.ios_dirtied.description.ios_wb.type", "WBThrottle.bytesDirtied.description.bytesWb.description.iosDirt"},
157 {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},
158 {"foo:bar", "FooBar"},
159 {"foo:bar+", "FooBarPlus"},
160 {"foo:bar-", "FooBarMinus"},
161 {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+", "AaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPlus"},
162 {"aa.bb.cc.dd.ee.ff", "Aa.bb.cc.dd.ee.ff"},
163 {"aa.bb.cc.dd.ee.ff.type", "Aa.bb.cc.dd.ee.ff"},
164 {"aa.type", "Aa.type"},
165 {"WBThrottle.bytes_dirtied.type", "WBThrottle.bytesDirtied"},
166 };
167 size_t i;
169 for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
170 {
171 char got[DATA_MAX_NAME_LEN];
173 CHECK_ZERO (parse_keys (got, sizeof (got), cases[i].str));
174 EXPECT_EQ_STR (cases[i].want, got);
175 }
177 return 0;
178 }
180 int main (void)
181 {
182 RUN_TEST(traverse_json);
183 RUN_TEST(parse_keys);
185 END_TEST;
186 }
188 /* vim: set sw=2 sts=2 et : */