blob: 41a1a2fd12cb79c5aa1b688ae33f921d6d14fc2d [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
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100262int
263main(void)
Radek Krejci36bac2b2018-09-19 11:15:29 +0200264{
265 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200266 UTEST(test_utf8),
267 UTEST(test_parse_int),
268 UTEST(test_parse_uint),
269 UTEST(test_parse_nodeid),
270 UTEST(test_parse_instance_predicate),
Radek Krejci36bac2b2018-09-19 11:15:29 +0200271 };
272
273 return cmocka_run_group_tests(tests, NULL, NULL);
274}