blob: b8425c7eac3bee4f91e2b8b9f0e82c240b07dec8 [file] [log] [blame]
Max70c7d412017-02-24 13:59:14 +01001#include <stdio.h>
2#include <stdlib.h>
3#include <stdint.h>
4#include <string.h>
5#include <stdbool.h>
6
7#include <osmocom/core/utils.h>
8#include <osmocom/ctrl/control_cmd.h>
Neels Hofmeyr505c9652017-09-26 15:24:58 +02009#include <osmocom/core/logging.h>
10#include <osmocom/core/msgb.h>
11#include <osmocom/core/application.h>
Max70c7d412017-02-24 13:59:14 +010012
Vadim Yanitskiyc2afe812017-06-13 01:43:23 +070013static void check_type(enum ctrl_type c)
Max70c7d412017-02-24 13:59:14 +010014{
15 const char *t = get_value_string(ctrl_type_vals, c);
16 int v = get_string_value(ctrl_type_vals, t);
17
18 printf("ctrl type %d is %s ", c, t);
19 if (v < 0)
20 printf("[PARSE FAILED]\n");
21 else
22 printf("-> %d %s\n", v, c != v ? "FAIL" : "OK");
23}
24
Neels Hofmeyr505c9652017-09-26 15:24:58 +020025struct msgb *msgb_from_string(const char *str)
26{
27 char *rc;
28 size_t len = strlen(str) + 1;
29 /* ctrl_cmd_parse() appends a '\0' to the msgb, allow one more byte. */
30 struct msgb *msg = msgb_alloc(len + 1, str);
31 msg->l2h = msg->head;
32 rc = (char*)msgb_put(msg, len);
33 OSMO_ASSERT(rc == (char*)msg->l2h);
34 strcpy(rc, str);
35 return msg;
36}
37
38static void *ctx = NULL;
39
40void print_escaped(const char *str)
41{
42 if (!str) {
43 printf("NULL");
44 return;
45 }
46
47 printf("'");
48 for (;*str; str++) {
49 switch (*str) {
50 case '\n':
51 printf("\\n");
52 break;
53 case '\r':
54 printf("\\r");
55 break;
56 case '\t':
57 printf("\\t");
58 break;
59 default:
60 printf("%c", *str);
61 break;
62 }
63 }
64 printf("'");
65}
66
67void assert_same_str(const char *label, const char *expect, const char *got)
68{
69 if ((expect == got) || (expect && got && (strcmp(expect, got) == 0))) {
70 printf("%s = ", label);
71 print_escaped(got);
72 printf("\n");
73 return;
74 }
75
76 printf("MISMATCH for '%s':\ngot: ", label); print_escaped(got);
77 printf("\nexpected: "); print_escaped(expect);
78 printf("\n");
79 OSMO_ASSERT(expect == got);
80}
81
82static void assert_parsing(const char *str, const struct ctrl_cmd *expect)
83{
84 struct ctrl_cmd *cmd;
85 struct msgb *msg = msgb_from_string(str);
86
87 printf("test parsing: ");
88 print_escaped(str);
89 printf("\n");
90
91 cmd = ctrl_cmd_parse(ctx, msg);
92 OSMO_ASSERT(cmd);
93
94 OSMO_ASSERT(expect->type == cmd->type);
95
96#define ASSERT_SAME_STR(field) \
97 assert_same_str(#field, expect->field, cmd->field)
98
99 ASSERT_SAME_STR(id);
100 ASSERT_SAME_STR(variable);
101 ASSERT_SAME_STR(value);
102 ASSERT_SAME_STR(reply);
103
104 talloc_free(cmd);
105 msgb_free(msg);
106
107 printf("ok\n");
108}
109
110struct one_parsing_test {
111 const char *cmd_str;
112 struct ctrl_cmd expect;
113};
114
115static const struct one_parsing_test test_parsing_list[] = {
116 { "GET 1 variable",
117 {
118 .type = CTRL_TYPE_GET,
119 .id = "1",
120 .variable = "variable",
121 }
122 },
123 { "GET 1 variable\n",
124 {
125 .type = CTRL_TYPE_GET,
126 .id = "1",
127 .variable = "variable\n", /* current bug */
128 }
129 },
130 { "GET 1 var\ni\nable",
131 {
132 .type = CTRL_TYPE_GET,
133 .id = "1",
134 .variable = "var\ni\nable", /* current bug */
135 }
136 },
137 { "GET 1 variable value",
138 {
139 .type = CTRL_TYPE_GET,
140 .id = "1",
141 .variable = "variable",
142 .value = NULL,
143 }
144 },
145 { "GET 1 variable value\n",
146 {
147 .type = CTRL_TYPE_GET,
148 .id = "1",
149 .variable = "variable",
150 .value = NULL,
151 }
152 },
153 { "GET 1 variable multiple value tokens",
154 {
155 .type = CTRL_TYPE_GET,
156 .id = "1",
157 .variable = "variable",
158 .value = NULL,
159 }
160 },
161 { "GET 1 variable multiple value tokens\n",
162 {
163 .type = CTRL_TYPE_GET,
164 .id = "1",
165 .variable = "variable",
166 .value = NULL,
167 }
168 },
169 { "SET 1 variable value",
170 {
171 .type = CTRL_TYPE_SET,
172 .id = "1",
173 .variable = "variable",
174 .value = "value",
175 }
176 },
177 { "SET 1 variable value\n",
178 {
179 .type = CTRL_TYPE_SET,
180 .id = "1",
181 .variable = "variable",
182 .value = "value",
183 }
184 },
185 { "SET weird_id variable value",
186 {
187 .type = CTRL_TYPE_SET,
188 .id = "weird_id",
189 .variable = "variable",
190 .value = "value",
191 }
192 },
193 { "SET weird_id variable value\n",
194 {
195 .type = CTRL_TYPE_SET,
196 .id = "weird_id",
197 .variable = "variable",
198 .value = "value",
199 }
200 },
201 { "SET 1 variable multiple value tokens",
202 {
203 .type = CTRL_TYPE_SET,
204 .id = "1",
205 .variable = "variable",
206 .value = "multiple value tokens",
207 }
208 },
209 { "SET 1 variable multiple value tokens\n",
210 {
211 .type = CTRL_TYPE_SET,
212 .id = "1",
213 .variable = "variable",
214 .value = "multiple value tokens",
215 }
216 },
217 { "SET 1 variable value_with_trailing_spaces ",
218 {
219 .type = CTRL_TYPE_SET,
220 .id = "1",
221 .variable = "variable",
222 .value = "value_with_trailing_spaces ",
223 }
224 },
225 { "SET 1 variable value_with_trailing_spaces \n",
226 {
227 .type = CTRL_TYPE_SET,
228 .id = "1",
229 .variable = "variable",
230 .value = "value_with_trailing_spaces ",
231 }
232 },
233 { "SET \n special_char_id value",
234 {
235 .type = CTRL_TYPE_SET,
236 .id = "\n",
237 .variable = "special_char_id",
238 .value = "value",
239 }
240 },
241 { "SET \t special_char_id value",
242 {
243 .type = CTRL_TYPE_SET,
244 .id = "\t",
245 .variable = "special_char_id",
246 .value = "value",
247 }
248 },
249};
250
251static void test_parsing()
252{
253 int i;
254
255 for (i = 0; i < ARRAY_SIZE(test_parsing_list); i++)
256 assert_parsing(test_parsing_list[i].cmd_str,
257 &test_parsing_list[i].expect);
258}
259
260static struct log_info_cat test_categories[] = {
261};
262
263static struct log_info info = {
264 .cat = test_categories,
265 .num_cat = ARRAY_SIZE(test_categories),
266};
267
Max70c7d412017-02-24 13:59:14 +0100268int main(int argc, char **argv)
269{
Neels Hofmeyr505c9652017-09-26 15:24:58 +0200270 ctx = talloc_named_const(NULL, 1, "ctrl_test");
271 osmo_init_logging(&info);
272
Max70c7d412017-02-24 13:59:14 +0100273 printf("Checking ctrl types...\n");
274
275 check_type(CTRL_TYPE_UNKNOWN);
276 check_type(CTRL_TYPE_GET);
277 check_type(CTRL_TYPE_SET);
278 check_type(CTRL_TYPE_GET_REPLY);
279 check_type(CTRL_TYPE_SET_REPLY);
280 check_type(CTRL_TYPE_TRAP);
281 check_type(CTRL_TYPE_ERROR);
282 check_type(64);
283
Neels Hofmeyr505c9652017-09-26 15:24:58 +0200284 test_parsing();
285
Max70c7d412017-02-24 13:59:14 +0100286 return 0;
287}