blob: a6c53c4b4cb0cb52b21ec73172e42187b2ba0344 [file] [log] [blame]
Radek Krejcie84f12f2018-09-18 14:11:50 +02001/*
2 * @file set.c
3 * @author: Radek Krejci <rkrejci@cesnet.cz>
4 * @brief unit tests for functions from set.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 */
14
15#define _BSD_SOURCE
16#define _DEFAULT_SOURCE
17#include <stdarg.h>
18#include <stddef.h>
19#include <setjmp.h>
20#include <cmocka.h>
21
22#include <string.h>
23
24#include "libyang.h"
25#include "../../src/set.c"
26
27#define BUFSIZE 1024
28char logbuf[BUFSIZE] = {0};
29
30static void
31logger(LY_LOG_LEVEL level, const char *msg, const char *path)
32{
33 (void) level; /* unused */
34 (void) path; /* unused */
35
36 strncpy(logbuf, msg, BUFSIZE - 1);
37}
38
39static int
40logger_setup(void **state)
41{
42 (void) state; /* unused */
43
44 ly_set_log_clb(logger, 0);
45
46 return 0;
47}
48
49static void
50test_basics(void **state)
51{
52 (void) state; /* unused */
53
54 struct ly_set *set;
55 char *str;
56 unsigned int u;
57 void *ptr;
58
59 /* creation - everything is empty */
60 set = ly_set_new();
61 assert_non_null(set);
62 assert_int_equal(0, set->count);
63 assert_int_equal(0, set->size);
64 assert_null(set->objs);
65
66 /* add a testing object */
67 str = strdup("test string");
68 assert_non_null(str);
69
70 ly_set_add(set, str, 0);
71 assert_int_not_equal(0, set->size);
72 assert_int_equal(1, set->count);
73 assert_non_null(set->objs);
74 assert_non_null(set->objs[0]);
75
76 /* check the presence of the testing data */
77 assert_int_equal(0, ly_set_contains(set, str));
78 assert_int_equal(-1, ly_set_contains(set, str - 1));
79
80 /* remove data, but keep the set */
81 u = set->size;
82 ptr = set->objs;
83 ly_set_clean(set, free);
84 assert_int_equal(0, set->count);
85 assert_int_equal(u, set->size);
86 assert_ptr_equal(ptr, set->objs);
87
88 /* remove buffer, but keep the set object */
89 ly_set_erase(set, NULL);
90 assert_int_equal(0, set->count);
91 assert_int_equal(0, set->size);
92 assert_ptr_equal(NULL, set->objs);
93
94 /* final cleanup */
95 ly_set_free(set, NULL);
96}
97
98static void
99test_inval(void **state)
100{
101 struct ly_set set;
102 memset(&set, 0, sizeof set);
103
104 ly_set_clean(NULL, NULL);
105 assert_string_equal(logbuf, "Invalid argument set (ly_set_clean()).");
106
107 ly_set_erase(NULL, NULL);
108 assert_string_equal(logbuf, "Invalid argument set (ly_set_erase()).");
109
110 ly_set_free(NULL, NULL);
111 assert_string_equal(logbuf, "Invalid argument set (ly_set_free()).");
112
Radek Krejci519b0432018-09-18 17:04:57 +0200113 assert_null(ly_set_dup(NULL, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200114 assert_string_equal(logbuf, "Invalid argument set (ly_set_dup()).");
115
116 assert_int_equal(-1, ly_set_add(NULL, NULL, 0));
117 assert_string_equal(logbuf, "Invalid argument set (ly_set_add()).");
118 assert_int_equal(-1, ly_set_add(&set, NULL, 0));
119 assert_string_equal(logbuf, "Invalid argument object (ly_set_add()).");
120
Radek Krejci519b0432018-09-18 17:04:57 +0200121 assert_int_equal(-1, ly_set_merge(NULL, NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200122 assert_string_equal(logbuf, "Invalid argument trg (ly_set_merge()).");
Radek Krejci519b0432018-09-18 17:04:57 +0200123 assert_int_equal(0, ly_set_merge(&set, NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200124 assert_string_equal(logbuf, "Invalid argument src (ly_set_merge()).");
125
Radek Krejci820d2262018-09-20 12:15:31 +0200126 assert_int_equal(LY_EINVAL, ly_set_rm_index(NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200127 assert_string_equal(logbuf, "Invalid argument set (ly_set_rm_index()).");
Radek Krejci820d2262018-09-20 12:15:31 +0200128 assert_int_equal(LY_EINVAL, ly_set_rm_index(&set, 1, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200129 assert_string_equal(logbuf, "Invalid argument index (ly_set_rm_index()).");
130
Radek Krejci820d2262018-09-20 12:15:31 +0200131 assert_int_equal(LY_EINVAL, ly_set_rm(NULL, NULL, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200132 assert_string_equal(logbuf, "Invalid argument set (ly_set_rm()).");
Radek Krejci820d2262018-09-20 12:15:31 +0200133 assert_int_equal(LY_EINVAL, ly_set_rm(&set, NULL, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200134 assert_string_equal(logbuf, "Invalid argument object (ly_set_rm()).");
Radek Krejci820d2262018-09-20 12:15:31 +0200135 assert_int_equal(LY_EINVAL, ly_set_rm(&set, &state, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200136 assert_string_equal(logbuf, "Invalid argument object (ly_set_rm()).");
137}
138
Radek Krejci519b0432018-09-18 17:04:57 +0200139static void
140test_duplication(void **state)
141{
142 (void) state; /* unused */
143
144 struct ly_set *orig, *new;
145 char *str;
146
147 orig = ly_set_new();
148 assert_non_null(orig);
149
150 /* add a testing object */
151 str = strdup("test string");
152 assert_non_null(str);
153 assert_int_equal(0, ly_set_add(orig, str, 0));
154
155 /* duplicate the set - without duplicator, so the new set will point to the same string */
156 new = ly_set_dup(orig, NULL);
157 assert_non_null(new);
158 assert_ptr_not_equal(orig, new);
159 assert_int_equal(orig->count, new->count);
160 assert_ptr_equal(orig->objs[0], new->objs[0]);
161
162 ly_set_free(new, NULL);
163
164 /* duplicate the set - with duplicator, so the new set will point to a different buffer with the same content */
165 new = ly_set_dup(orig, (void*(*)(void*))strdup);
166 assert_non_null(new);
167 assert_ptr_not_equal(orig, new);
168 assert_int_equal(orig->count, new->count);
169 assert_ptr_not_equal(orig->objs[0], new->objs[0]);
170 assert_string_equal(orig->objs[0], new->objs[0]);
171
172 /* cleanup */
173 ly_set_free(new, free);
174 ly_set_free(orig, free);
175}
176
177static void
178test_add(void **state)
179{
180 (void) state; /* unused */
181
182 unsigned int u, i;
183 char *str = "test string";
184 struct ly_set set;
185 memset(&set, 0, sizeof set);
186
187 /* add a testing object */
188 assert_int_equal(0, ly_set_add(&set, str, 0));
189
190 /* test avoiding data duplicities */
191 assert_int_equal(0, ly_set_add(&set, str, 0));
192 assert_int_equal(1, set.count);
193 assert_int_equal(1, ly_set_add(&set, str, LY_SET_OPT_USEASLIST));
194 assert_int_equal(2, set.count);
195
196 /* test array resizing */
197 u = set.size;
198 for (i = 2; i <= u; ++i) {
199 assert_int_equal(i, ly_set_add(&set, str, LY_SET_OPT_USEASLIST));
200 }
201 assert_true(u != set.size);
202
203 /* cleanup */
204 ly_set_erase(&set, NULL);
205}
206
207static void
208test_merge(void **state)
209{
210 (void) state; /* unused */
211
212 char *str1, *str2;
213 struct ly_set one, two;
214 memset(&one, 0, sizeof one);
215 memset(&two, 0, sizeof two);
216
217 str1 = strdup("string1");
218 str2 = strdup("string2");
219
220 /* fill first set
221 * - str1 is the same as in two, so it must not be freed! */
222 assert_int_equal(0, ly_set_add(&one, str1, 0));
223
224 /* fill second set */
225 assert_int_equal(0, ly_set_add(&two, str1, 0));
226 assert_int_equal(1, ly_set_add(&two, str2, 0));
227
228 /* merge with checking duplicities - only one item is added into one;
229 * also without duplicating data, so it must not be freed at the end */
230 assert_int_equal(1, ly_set_merge(&one, &two, 0, NULL));
231 assert_ptr_equal(one.objs[1], two.objs[1]);
232
233 /* clean and re-fill one (now duplicating str1, to allow testing duplicator) */
234 ly_set_clean(&one, NULL);
235 assert_int_equal(0, ly_set_add(&one, strdup(str1), 0));
236
237 /* merge without checking duplicities - two items are added into one;
238 * here also with duplicator */
239 assert_int_equal(2, ly_set_merge(&one, &two, LY_SET_OPT_USEASLIST, (void*(*)(void*))strdup));
240 assert_ptr_not_equal(one.objs[1], two.objs[0]);
241 assert_string_equal(one.objs[1], two.objs[0]);
242
243 /* cleanup */
244 ly_set_erase(&one, free);
245 ly_set_erase(&two, free);
246}
247
248static void
249test_rm(void **state)
250{
251 (void) state; /* unused */
252
253 char *str1, *str2, *str3;
254 struct ly_set set;
255 memset(&set, 0, sizeof set);
256
257 /* fill the set */
258 assert_int_equal(0, ly_set_add(&set, "string1", 0));
Radek Krejci820d2262018-09-20 12:15:31 +0200259 assert_int_equal(1, ly_set_add(&set, strdup("string2"), 0));
Radek Krejci519b0432018-09-18 17:04:57 +0200260 assert_int_equal(2, ly_set_add(&set, "string3", 0));
261
262 /* remove by index ... */
263 /* ... in the middle ... */
Radek Krejci820d2262018-09-20 12:15:31 +0200264 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 1, free));
Radek Krejci519b0432018-09-18 17:04:57 +0200265 assert_int_equal(2, set.count);
266 assert_string_not_equal("string2", set.objs[0]);
267 assert_string_not_equal("string2", set.objs[1]);
268 /* ... last .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200269 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 1, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200270 assert_int_equal(1, set.count);
271 assert_string_not_equal("string3", set.objs[0]);
272 /* ... first .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200273 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200274 assert_int_equal(0, set.count);
275
276 /* fill the set */
277 assert_int_equal(0, ly_set_add(&set, str1 = "string1", 0));
278 assert_int_equal(1, ly_set_add(&set, str2 = "string2", 0));
Radek Krejci820d2262018-09-20 12:15:31 +0200279 assert_int_equal(2, ly_set_add(&set, str3 = strdup("string3"), 0));
Radek Krejci519b0432018-09-18 17:04:57 +0200280
281 /* remove by pointer ... */
282 /* ... in the middle ... */
Radek Krejci820d2262018-09-20 12:15:31 +0200283 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str2, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200284 assert_int_equal(2, set.count);
285 assert_string_not_equal("string2", set.objs[0]);
286 assert_string_not_equal("string2", set.objs[1]);
Radek Krejci820d2262018-09-20 12:15:31 +0200287 /* ... last (with destructor) .. */
288 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str3, free));
Radek Krejci519b0432018-09-18 17:04:57 +0200289 assert_int_equal(1, set.count);
290 assert_string_not_equal("string3", set.objs[0]);
291 /* ... first .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200292 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str1, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200293 assert_int_equal(0, set.count);
294
295 /* cleanup */
296 ly_set_erase(&set, NULL);
297}
298
Radek Krejcie84f12f2018-09-18 14:11:50 +0200299int main(void)
300{
301 const struct CMUnitTest tests[] = {
302 cmocka_unit_test(test_basics),
Radek Krejci519b0432018-09-18 17:04:57 +0200303 cmocka_unit_test(test_duplication),
304 cmocka_unit_test(test_add),
305 cmocka_unit_test(test_merge),
306 cmocka_unit_test(test_rm),
Radek Krejcie84f12f2018-09-18 14:11:50 +0200307 cmocka_unit_test_setup(test_inval, logger_setup),
308 };
309
310 return cmocka_run_group_tests(tests, NULL, NULL);
311}