blob: 671ef563c8d542fac34dd301e334a6fc277cb447 [file] [log] [blame]
Radek Krejci36bac2b2018-09-19 11:15:29 +02001/*
2 * @file set.c
3 * @author: Radek Krejci <rkrejci@cesnet.cz>
4 * @brief unit tests for functions from common.c
5 *
6 * Copyright (c) 2018 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
Radek Iša56ca9e42020-09-08 18:42:00 +020014#define _UTEST_MAIN_
Radek Krejcib4ac5a92020-11-23 17:54:33 +010015#include "utests.h"
Radek Krejci36bac2b2018-09-19 11:15:29 +020016
Radek Iša56ca9e42020-09-08 18:42:00 +020017#include "common.h"
Radek Krejcib4a4a272019-06-10 12:44:52 +020018
Radek Krejci36bac2b2018-09-19 11:15:29 +020019static void
Radek Iša56ca9e42020-09-08 18:42:00 +020020test_utf8(void **UNUSED(state))
Radek Krejci44ceedc2018-10-02 15:54:31 +020021{
Radek Krejci44ceedc2018-10-02 15:54:31 +020022 char buf[5] = {0};
23 const char *str = buf;
24 unsigned int c;
25 size_t len;
26
27 /* test invalid UTF-8 characters in lyxml_getutf8
28 * - https://en.wikipedia.org/wiki/UTF-8 */
29 buf[0] = 0x04;
30 assert_int_equal(LY_EINVAL, ly_getutf8(&str, &c, &len));
31 buf[0] = 0x80;
32 assert_int_equal(LY_EINVAL, ly_getutf8(&str, &c, &len));
33
34 buf[0] = 0xc0;
35 buf[1] = 0x00;
36 assert_int_equal(LY_EINVAL, ly_getutf8(&str, &c, &len));
37 buf[1] = 0x80;
38 assert_int_equal(LY_EINVAL, ly_getutf8(&str, &c, &len));
39
40 buf[0] = 0xe0;
41 buf[1] = 0x00;
42 buf[2] = 0x80;
43 assert_int_equal(LY_EINVAL, ly_getutf8(&str, &c, &len));
44 buf[1] = 0x80;
45 assert_int_equal(LY_EINVAL, ly_getutf8(&str, &c, &len));
46
47 buf[0] = 0xf0;
48 buf[1] = 0x00;
49 buf[2] = 0x80;
50 buf[3] = 0x80;
51 assert_int_equal(LY_EINVAL, ly_getutf8(&str, &c, &len));
52 buf[1] = 0x80;
53 assert_int_equal(LY_EINVAL, ly_getutf8(&str, &c, &len));
54}
55
Radek Krejci36bac2b2018-09-19 11:15:29 +020056static void
Radek Iša56ca9e42020-09-08 18:42:00 +020057test_parse_int(void **UNUSED(state))
Radek Krejci36bac2b2018-09-19 11:15:29 +020058{
Radek Krejci9ea8ca12019-06-10 13:11:55 +020059 const char *str;
60 int64_t i = 500;
61
62 str = "10";
63 assert_int_equal(LY_SUCCESS, ly_parse_int(str, strlen(str), -10, 10, 10, &i));
64 assert_int_equal(i, 10);
65
66 /* leading zeros are allowed, trailing whitespaces are allowed */
67 str = "000\n\t ";
68 assert_int_equal(LY_SUCCESS, ly_parse_int(str, strlen(str), -10, 10, 10, &i));
69 assert_int_equal(i, 0);
70
71 /* negative value */
72 str = "-10";
73 assert_int_equal(LY_SUCCESS, ly_parse_int(str, strlen(str), -10, 10, 10, &i));
74 assert_int_equal(i, -10);
75
76 /* non-NULL terminated string */
77 str = "+5sometext";
78 assert_int_equal(LY_SUCCESS, ly_parse_int(str, 2, -10, 10, 10, &i));
79 assert_int_equal(i, 5);
80
81 /* out of bounds value */
82 str = "11";
83 assert_int_equal(LY_EDENIED, ly_parse_int(str, strlen(str), -10, 10, 10, &i));
84 str = "-11";
85 assert_int_equal(LY_EDENIED, ly_parse_int(str, strlen(str), -10, 10, 10, &i));
86
87 /* NaN */
88 str = "zero";
89 assert_int_equal(LY_EVALID, ly_parse_int(str, strlen(str), -10, 10, 10, &i));
90
91 /* mixing number with text */
92 str = "10zero";
93 assert_int_equal(LY_EVALID, ly_parse_int(str, strlen(str), -10, 10, 10, &i));
94
95 str = "10 zero";
96 assert_int_equal(LY_EVALID, ly_parse_int(str, strlen(str), -10, 10, 10, &i));
Radek Krejci9ea8ca12019-06-10 13:11:55 +020097}
98
99static void
Radek Iša56ca9e42020-09-08 18:42:00 +0200100test_parse_uint(void **UNUSED(state))
Radek Krejci9ea8ca12019-06-10 13:11:55 +0200101{
Radek Krejci9ea8ca12019-06-10 13:11:55 +0200102 const char *str;
103 uint64_t u = 500;
104
105 str = "10";
106 assert_int_equal(LY_SUCCESS, ly_parse_uint(str, strlen(str), 10, 10, &u));
107 assert_int_equal(u, 10);
108
109 /* leading zeros are allowed, trailing whitespaces are allowed */
110 str = "000\n\t ";
111 assert_int_equal(LY_SUCCESS, ly_parse_uint(str, strlen(str), 10, 10, &u));
112 assert_int_equal(u, 0);
113 /* non-NULL terminated string */
114 str = "+5sometext";
115 assert_int_equal(LY_SUCCESS, ly_parse_uint(str, 2, 10, 10, &u));
116 assert_int_equal(u, 5);
117
118 /* out of bounds value */
119 str = "11";
120 assert_int_equal(LY_EDENIED, ly_parse_uint(str, strlen(str), 10, 10, &u));
121 str = "-1";
122 assert_int_equal(LY_EDENIED, ly_parse_uint(str, strlen(str), (uint64_t)-1, 10, &u));
123
124 /* NaN */
125 str = "zero";
126 assert_int_equal(LY_EVALID, ly_parse_uint(str, strlen(str), 10, 10, &u));
127
128 /* mixing number with text */
129 str = "10zero";
130 assert_int_equal(LY_EVALID, ly_parse_uint(str, strlen(str), 10, 10, &u));
131
132 str = "10 zero";
133 assert_int_equal(LY_EVALID, ly_parse_uint(str, strlen(str), 10, 10, &u));
Radek Krejci9ea8ca12019-06-10 13:11:55 +0200134}
135
136static void
Radek Iša56ca9e42020-09-08 18:42:00 +0200137test_parse_nodeid(void **UNUSED(state))
Radek Krejcib4a4a272019-06-10 12:44:52 +0200138{
Radek Krejcib4a4a272019-06-10 12:44:52 +0200139 const char *str;
140 const char *prefix, *name;
141 size_t prefix_len, name_len;
142
143 str = "123";
144 assert_int_equal(LY_EINVAL, ly_parse_nodeid(&str, &prefix, &prefix_len, &name, &name_len));
145
146 str = "a12_-.!";
147 assert_int_equal(LY_SUCCESS, ly_parse_nodeid(&str, &prefix, &prefix_len, &name, &name_len));
148 assert_null(prefix);
149 assert_int_equal(0, prefix_len);
150 assert_non_null(name);
151 assert_int_equal(6, name_len);
152 assert_int_equal(0, strncmp("a12_-.", name, name_len));
153 assert_string_equal("!", str);
154
155 str = "a12_-.:_b2 xxx";
156 assert_int_equal(LY_SUCCESS, ly_parse_nodeid(&str, &prefix, &prefix_len, &name, &name_len));
157 assert_non_null(prefix);
158 assert_int_equal(6, prefix_len);
159 assert_int_equal(0, strncmp("a12_-.", prefix, prefix_len));
160 assert_non_null(name);
161 assert_int_equal(3, name_len);
162 assert_int_equal(0, strncmp("_b2", name, name_len));
163 assert_string_equal(" xxx", str);
Radek Krejci10bfdf82019-06-10 14:08:13 +0200164}
165
166static void
Radek Iša56ca9e42020-09-08 18:42:00 +0200167test_parse_instance_predicate(void **UNUSED(state))
Radek Krejci10bfdf82019-06-10 14:08:13 +0200168{
Radek Krejci10bfdf82019-06-10 14:08:13 +0200169 const char *str, *errmsg;
170 const char *prefix, *id, *value;
171 size_t prefix_len, id_len, value_len;
172
173 str = "[ex:name='fred']";
Radek Krejci084289f2019-07-09 17:35:30 +0200174 assert_int_equal(LY_SUCCESS, ly_parse_instance_predicate(&str, strlen(str), LYD_XML, &prefix, &prefix_len, &id, &id_len, &value, &value_len, &errmsg));
Radek Krejci10bfdf82019-06-10 14:08:13 +0200175 assert_string_equal(str, "");
176 assert_string_equal(prefix, "ex:name='fred']");
177 assert_int_equal(prefix_len, 2);
178 assert_string_equal(id, "name='fred']");
179 assert_int_equal(id_len, 4);
180 assert_string_equal(value, "fred']");
181 assert_int_equal(value_len, 4);
182
183 str = "[ex:ip = \"[192.0.2.1]\"][ex:port='80']";
Radek Krejci084289f2019-07-09 17:35:30 +0200184 assert_int_equal(LY_SUCCESS, ly_parse_instance_predicate(&str, strlen(str), LYD_XML, &prefix, &prefix_len, &id, &id_len, &value, &value_len, &errmsg));
Radek Krejci10bfdf82019-06-10 14:08:13 +0200185 assert_string_equal(str, "[ex:port='80']");
186 assert_string_equal(prefix, "ex:ip = \"[192.0.2.1]\"][ex:port='80']");
187 assert_int_equal(prefix_len, 2);
188 assert_string_equal(id, "ip = \"[192.0.2.1]\"][ex:port='80']");
189 assert_int_equal(id_len, 2);
190 assert_string_equal(value, "[192.0.2.1]\"][ex:port='80']");
191 assert_int_equal(value_len, 11);
192
193 str = "[. = 'blowfish-cbc']";
Radek Krejci084289f2019-07-09 17:35:30 +0200194 assert_int_equal(LY_SUCCESS, ly_parse_instance_predicate(&str, strlen(str), LYD_XML, &prefix, &prefix_len, &id, &id_len, &value, &value_len, &errmsg));
Radek Krejci10bfdf82019-06-10 14:08:13 +0200195 assert_string_equal(str, "");
196 assert_null(prefix);
197 assert_int_equal(prefix_len, 0);
198 assert_string_equal(id, ". = 'blowfish-cbc']");
199 assert_int_equal(id_len, 1);
200 assert_string_equal(value, "blowfish-cbc']");
201 assert_int_equal(value_len, 12);
202
203 str = "[ 3 ]";
Radek Krejci084289f2019-07-09 17:35:30 +0200204 assert_int_equal(LY_SUCCESS, ly_parse_instance_predicate(&str, strlen(str), LYD_XML, &prefix, &prefix_len, &id, &id_len, &value, &value_len, &errmsg));
Radek Krejci10bfdf82019-06-10 14:08:13 +0200205 assert_string_equal(str, "");
206 assert_null(prefix);
207 assert_int_equal(prefix_len, 0);
208 assert_null(id);
209 assert_int_equal(id_len, 0);
210 assert_string_equal(value, "3 ]");
211 assert_int_equal(value_len, 1);
212
213 /* invalid predicates */
214 /* position must be positive integer */
215 str = "[0]";
Radek Krejci084289f2019-07-09 17:35:30 +0200216 assert_int_equal(LY_EVALID, ly_parse_instance_predicate(&str, strlen(str), LYD_XML, &prefix, &prefix_len, &id, &id_len, &value, &value_len, &errmsg));
Radek Krejci10bfdf82019-06-10 14:08:13 +0200217 assert_string_equal(errmsg, "The position predicate cannot be zero.");
218 str = "[-1]";
Radek Krejci084289f2019-07-09 17:35:30 +0200219 assert_int_equal(LY_EVALID, ly_parse_instance_predicate(&str, strlen(str), LYD_XML, &prefix, &prefix_len, &id, &id_len, &value, &value_len, &errmsg));
Radek Krejci10bfdf82019-06-10 14:08:13 +0200220 assert_string_equal(errmsg, "Invalid instance predicate format (negative position or invalid node-identifier).");
221
222 /* invalid node-identifier */
223 str = "[$node='value']";
Radek Krejci084289f2019-07-09 17:35:30 +0200224 assert_int_equal(LY_EVALID, ly_parse_instance_predicate(&str, strlen(str), LYD_XML, &prefix, &prefix_len, &id, &id_len, &value, &value_len, &errmsg));
Radek Krejci10bfdf82019-06-10 14:08:13 +0200225 assert_string_equal(errmsg, "Invalid node-identifier.");
226 str = "[.node='value']";
Radek Krejci084289f2019-07-09 17:35:30 +0200227 assert_int_equal(LY_EVALID, ly_parse_instance_predicate(&str, strlen(str), LYD_XML, &prefix, &prefix_len, &id, &id_len, &value, &value_len, &errmsg));
Radek Krejci10bfdf82019-06-10 14:08:13 +0200228 assert_string_equal(errmsg, "Unexpected character instead of '=' in leaf-list-predicate.");
229 str = "[13node='value']";
Radek Krejci084289f2019-07-09 17:35:30 +0200230 assert_int_equal(LY_EVALID, ly_parse_instance_predicate(&str, strlen(str), LYD_XML, &prefix, &prefix_len, &id, &id_len, &value, &value_len, &errmsg));
Radek Krejci10bfdf82019-06-10 14:08:13 +0200231 assert_string_equal(errmsg, "Predicate (pos) is not terminated by \']\' character.");
232
Radek Krejci084289f2019-07-09 17:35:30 +0200233 str = "[ex:node]";
234 assert_int_equal(LY_EVALID, ly_parse_instance_predicate(&str, strlen(str), LYD_XML, &prefix, &prefix_len, &id, &id_len, &value, &value_len, &errmsg));
Radek Krejci10bfdf82019-06-10 14:08:13 +0200235 assert_string_equal(errmsg, "Unexpected character instead of '=' in key-predicate.");
236
Radek Krejci084289f2019-07-09 17:35:30 +0200237 str = "[ex:node= value]";
238 assert_int_equal(LY_EVALID, ly_parse_instance_predicate(&str, strlen(str), LYD_XML, &prefix, &prefix_len, &id, &id_len, &value, &value_len, &errmsg));
Radek Krejci10bfdf82019-06-10 14:08:13 +0200239 assert_string_equal(errmsg, "String value is not quoted.");
240
Radek Krejci084289f2019-07-09 17:35:30 +0200241 str = "[ex:node='value\"]";
242 assert_int_equal(LY_EVALID, ly_parse_instance_predicate(&str, strlen(str), LYD_XML, &prefix, &prefix_len, &id, &id_len, &value, &value_len, &errmsg));
Radek Krejci10bfdf82019-06-10 14:08:13 +0200243 assert_string_equal(errmsg, "Value is not terminated quoted-string.");
244
Radek Krejci084289f2019-07-09 17:35:30 +0200245 str = "[ex:node='value ]";
246 assert_int_equal(LY_EVALID, ly_parse_instance_predicate(&str, strlen(str), LYD_XML, &prefix, &prefix_len, &id, &id_len, &value, &value_len, &errmsg));
Radek Krejci10bfdf82019-06-10 14:08:13 +0200247 assert_string_equal(errmsg, "Value is not terminated quoted-string.");
248
Radek Krejci084289f2019-07-09 17:35:30 +0200249 str = "[ex:node=\"value\"[3]";
250 assert_int_equal(LY_EVALID, ly_parse_instance_predicate(&str, strlen(str), LYD_XML, &prefix, &prefix_len, &id, &id_len, &value, &value_len, &errmsg));
Radek Krejci10bfdf82019-06-10 14:08:13 +0200251 assert_string_equal(errmsg, "Predicate (key-predicate) is not terminated by \']\' character.");
252 str = "[.=\"value\"[3]";
Radek Krejci084289f2019-07-09 17:35:30 +0200253 assert_int_equal(LY_EVALID, ly_parse_instance_predicate(&str, strlen(str), LYD_XML, &prefix, &prefix_len, &id, &id_len, &value, &value_len, &errmsg));
Radek Krejci10bfdf82019-06-10 14:08:13 +0200254 assert_string_equal(errmsg, "Predicate (leaf-list-predicate) is not terminated by \']\' character.");
255
Radek Krejci084289f2019-07-09 17:35:30 +0200256 /* the limit of the string is too short, it ends one character earlier */
257 str = "[ex:node='value']";
258 assert_int_equal(LY_EINVAL, ly_parse_instance_predicate(&str, strlen(str) - 1, LYD_XML, &prefix, &prefix_len, &id, &id_len, &value, &value_len, &errmsg));
Radek Krejci10bfdf82019-06-10 14:08:13 +0200259 assert_string_equal(errmsg, "Predicate is incomplete.");
Radek Krejcib4a4a272019-06-10 12:44:52 +0200260}
261
aPiecekf0d81232021-03-30 12:19:59 +0200262static void
263test_value_prefix_next(void **UNUSED(state))
264{
265 const char *next;
266 ly_bool is_prefix;
267
268 assert_int_equal(0, ly_value_prefix_next(NULL, NULL, &is_prefix, &next));
269 assert_int_equal(0, ly_value_prefix_next("", NULL, &is_prefix, &next));
270
271 /* prefix */
272 next = "pref:";
273 assert_int_equal(4, ly_value_prefix_next(next, NULL, &is_prefix, &next));
274 assert_null(next);
275 assert_int_equal(1, is_prefix);
276
277 /* no-prefix */
278 next = "node";
279 assert_int_equal(4, ly_value_prefix_next(next, NULL, &is_prefix, &next));
280 assert_null(next);
281 assert_int_equal(0, is_prefix);
282
283 /* no-prefix */
284 next = "::::";
285 assert_int_equal(4, ly_value_prefix_next(next, NULL, &is_prefix, &next));
286 assert_null(next);
287 assert_int_equal(0, is_prefix);
288
289 /* no-prefix */
290 next = "//a/:";
291 assert_int_equal(5, ly_value_prefix_next(next, NULL, &is_prefix, &next));
292 assert_null(next);
293 assert_int_equal(0, is_prefix);
294
295 /* no-prefix */
296 next = "//a//";
297 assert_int_equal(5, ly_value_prefix_next(next, NULL, &is_prefix, &next));
298 assert_null(next);
299 assert_int_equal(0, is_prefix);
300
301 /* prefix, prefix */
302 next = "pref1:pref2:";
303 assert_int_equal(5, ly_value_prefix_next(next, NULL, &is_prefix, &next));
304 assert_string_equal(next, "pref2:");
305 assert_int_equal(1, is_prefix);
306 assert_int_equal(5, ly_value_prefix_next(next, NULL, &is_prefix, &next));
307 assert_null(next);
308 assert_int_equal(1, is_prefix);
309
310 /* prefix, no-prefix */
311 next = "pref:node";
312 assert_int_equal(4, ly_value_prefix_next(next, NULL, &is_prefix, &next));
313 assert_string_equal(next, "node");
314 assert_int_equal(1, is_prefix);
315 assert_int_equal(4, ly_value_prefix_next(next, NULL, &is_prefix, &next));
316 assert_null(next);
317 assert_int_equal(0, is_prefix);
318
319 /* no-prefix, prefix */
320 next = "/pref:";
321 assert_int_equal(1, ly_value_prefix_next(next, NULL, &is_prefix, &next));
322 assert_string_equal(next, "pref:");
323 assert_int_equal(0, is_prefix);
324 assert_int_equal(4, ly_value_prefix_next(next, NULL, &is_prefix, &next));
325 assert_null(next);
326 assert_int_equal(1, is_prefix);
327
328 /* no-prefix, prefix */
329 next = "//pref:";
330 assert_int_equal(2, ly_value_prefix_next(next, NULL, &is_prefix, &next));
331 assert_string_equal(next, "pref:");
332 assert_int_equal(0, is_prefix);
333 assert_int_equal(4, ly_value_prefix_next(next, NULL, &is_prefix, &next));
334 assert_null(next);
335 assert_int_equal(1, is_prefix);
336
337 /* no-prefix, prefix, no-prefix */
Radek Krejci12a28c72021-04-06 17:23:37 +0200338 next = "/pref:node";
aPiecekf0d81232021-03-30 12:19:59 +0200339 assert_int_equal(1, ly_value_prefix_next(next, NULL, &is_prefix, &next));
340 assert_string_equal(next, "pref:node");
341 assert_int_equal(0, is_prefix);
342 assert_int_equal(4, ly_value_prefix_next(next, NULL, &is_prefix, &next));
343 assert_string_equal(next, "node");
344 assert_int_equal(1, is_prefix);
345 assert_int_equal(4, ly_value_prefix_next(next, NULL, &is_prefix, &next));
346 assert_null(next);
347 assert_int_equal(0, is_prefix);
348
349 /* prefix, no-prefix, prefix */
Radek Krejci12a28c72021-04-06 17:23:37 +0200350 next = "pref:node pref:";
aPiecekf0d81232021-03-30 12:19:59 +0200351 assert_int_equal(4, ly_value_prefix_next(next, NULL, &is_prefix, &next));
352 assert_string_equal(next, "node pref:");
353 assert_int_equal(1, is_prefix);
354 assert_int_equal(5, ly_value_prefix_next(next, NULL, &is_prefix, &next));
355 assert_string_equal(next, "pref:");
356 assert_int_equal(0, is_prefix);
357 assert_int_equal(4, ly_value_prefix_next(next, NULL, &is_prefix, &next));
358 assert_null(next);
359 assert_int_equal(1, is_prefix);
360
361 /* prefix, no-prefix, prefix, no-prefix */
362 next = "pref:node /pref:node";
363 assert_int_equal(4, ly_value_prefix_next(next, NULL, &is_prefix, &next));
364 assert_string_equal(next, "node /pref:node");
365 assert_int_equal(1, is_prefix);
366 assert_int_equal(6, ly_value_prefix_next(next, NULL, &is_prefix, &next));
367 assert_string_equal(next, "pref:node");
368 assert_int_equal(0, is_prefix);
369 assert_int_equal(4, ly_value_prefix_next(next, NULL, &is_prefix, &next));
370 assert_string_equal(next, "node");
371 assert_int_equal(1, is_prefix);
372 assert_int_equal(4, ly_value_prefix_next(next, NULL, &is_prefix, &next));
373 assert_null(next);
374 assert_int_equal(0, is_prefix);
375}
376
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100377int
378main(void)
Radek Krejci36bac2b2018-09-19 11:15:29 +0200379{
380 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200381 UTEST(test_utf8),
382 UTEST(test_parse_int),
383 UTEST(test_parse_uint),
384 UTEST(test_parse_nodeid),
385 UTEST(test_parse_instance_predicate),
aPiecekf0d81232021-03-30 12:19:59 +0200386 UTEST(test_value_prefix_next),
Radek Krejci36bac2b2018-09-19 11:15:29 +0200387 };
388
389 return cmocka_run_group_tests(tests, NULL, NULL);
390}