blob: a4e43323013c39126400b93cf61ad8a9610d757e [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 */
Radek Krejcib7db73a2018-10-24 14:18:40 +020014#include "common.h"
Radek Krejcie84f12f2018-09-18 14:11:50 +020015
Radek Krejcie84f12f2018-09-18 14:11:50 +020016#include <stdarg.h>
17#include <stddef.h>
18#include <setjmp.h>
19#include <cmocka.h>
20
21#include <string.h>
22
Radek Krejci2d7a47b2019-05-16 13:34:10 +020023#include "../../src/set.h"
Radek Krejcie84f12f2018-09-18 14:11:50 +020024
25#define BUFSIZE 1024
26char logbuf[BUFSIZE] = {0};
27
28static void
29logger(LY_LOG_LEVEL level, const char *msg, const char *path)
30{
31 (void) level; /* unused */
32 (void) path; /* unused */
33
34 strncpy(logbuf, msg, BUFSIZE - 1);
35}
36
37static int
38logger_setup(void **state)
39{
40 (void) state; /* unused */
41
42 ly_set_log_clb(logger, 0);
43
44 return 0;
45}
46
47static void
48test_basics(void **state)
49{
50 (void) state; /* unused */
51
52 struct ly_set *set;
53 char *str;
54 unsigned int u;
55 void *ptr;
56
57 /* creation - everything is empty */
58 set = ly_set_new();
59 assert_non_null(set);
60 assert_int_equal(0, set->count);
61 assert_int_equal(0, set->size);
62 assert_null(set->objs);
63
64 /* add a testing object */
65 str = strdup("test string");
66 assert_non_null(str);
67
68 ly_set_add(set, str, 0);
69 assert_int_not_equal(0, set->size);
70 assert_int_equal(1, set->count);
71 assert_non_null(set->objs);
72 assert_non_null(set->objs[0]);
73
74 /* check the presence of the testing data */
75 assert_int_equal(0, ly_set_contains(set, str));
76 assert_int_equal(-1, ly_set_contains(set, str - 1));
77
78 /* remove data, but keep the set */
79 u = set->size;
80 ptr = set->objs;
81 ly_set_clean(set, free);
82 assert_int_equal(0, set->count);
83 assert_int_equal(u, set->size);
84 assert_ptr_equal(ptr, set->objs);
85
86 /* remove buffer, but keep the set object */
87 ly_set_erase(set, NULL);
88 assert_int_equal(0, set->count);
89 assert_int_equal(0, set->size);
90 assert_ptr_equal(NULL, set->objs);
91
92 /* final cleanup */
93 ly_set_free(set, NULL);
94}
95
96static void
97test_inval(void **state)
98{
99 struct ly_set set;
100 memset(&set, 0, sizeof set);
101
102 ly_set_clean(NULL, NULL);
Radek Krejci0bfec162019-05-02 09:54:25 +0200103 assert_string_equal(logbuf, "");
Radek Krejcie84f12f2018-09-18 14:11:50 +0200104
105 ly_set_erase(NULL, NULL);
Radek Krejci0bfec162019-05-02 09:54:25 +0200106 assert_string_equal(logbuf, "");
Radek Krejcie84f12f2018-09-18 14:11:50 +0200107
108 ly_set_free(NULL, NULL);
Radek Krejci0bfec162019-05-02 09:54:25 +0200109 assert_string_equal(logbuf, "");
Radek Krejcie84f12f2018-09-18 14:11:50 +0200110
Radek Krejci519b0432018-09-18 17:04:57 +0200111 assert_null(ly_set_dup(NULL, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200112 assert_string_equal(logbuf, "Invalid argument set (ly_set_dup()).");
113
114 assert_int_equal(-1, ly_set_add(NULL, NULL, 0));
115 assert_string_equal(logbuf, "Invalid argument set (ly_set_add()).");
Radek Krejcie84f12f2018-09-18 14:11:50 +0200116
Radek Krejci519b0432018-09-18 17:04:57 +0200117 assert_int_equal(-1, ly_set_merge(NULL, NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200118 assert_string_equal(logbuf, "Invalid argument trg (ly_set_merge()).");
Radek Krejci519b0432018-09-18 17:04:57 +0200119 assert_int_equal(0, ly_set_merge(&set, NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200120 assert_string_equal(logbuf, "Invalid argument src (ly_set_merge()).");
121
Radek Krejci820d2262018-09-20 12:15:31 +0200122 assert_int_equal(LY_EINVAL, ly_set_rm_index(NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200123 assert_string_equal(logbuf, "Invalid argument set (ly_set_rm_index()).");
Radek Krejci820d2262018-09-20 12:15:31 +0200124 assert_int_equal(LY_EINVAL, ly_set_rm_index(&set, 1, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200125 assert_string_equal(logbuf, "Invalid argument index (ly_set_rm_index()).");
126
Radek Krejci820d2262018-09-20 12:15:31 +0200127 assert_int_equal(LY_EINVAL, ly_set_rm(NULL, NULL, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200128 assert_string_equal(logbuf, "Invalid argument set (ly_set_rm()).");
Radek Krejci820d2262018-09-20 12:15:31 +0200129 assert_int_equal(LY_EINVAL, ly_set_rm(&set, NULL, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200130 assert_string_equal(logbuf, "Invalid argument object (ly_set_rm()).");
Radek Krejci820d2262018-09-20 12:15:31 +0200131 assert_int_equal(LY_EINVAL, ly_set_rm(&set, &state, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200132 assert_string_equal(logbuf, "Invalid argument object (ly_set_rm()).");
133}
134
Radek Krejci519b0432018-09-18 17:04:57 +0200135static void
136test_duplication(void **state)
137{
138 (void) state; /* unused */
139
140 struct ly_set *orig, *new;
141 char *str;
142
143 orig = ly_set_new();
144 assert_non_null(orig);
145
146 /* add a testing object */
147 str = strdup("test string");
148 assert_non_null(str);
149 assert_int_equal(0, ly_set_add(orig, str, 0));
150
151 /* duplicate the set - without duplicator, so the new set will point to the same string */
152 new = ly_set_dup(orig, NULL);
153 assert_non_null(new);
154 assert_ptr_not_equal(orig, new);
155 assert_int_equal(orig->count, new->count);
156 assert_ptr_equal(orig->objs[0], new->objs[0]);
157
158 ly_set_free(new, NULL);
159
160 /* duplicate the set - with duplicator, so the new set will point to a different buffer with the same content */
161 new = ly_set_dup(orig, (void*(*)(void*))strdup);
162 assert_non_null(new);
163 assert_ptr_not_equal(orig, new);
164 assert_int_equal(orig->count, new->count);
165 assert_ptr_not_equal(orig->objs[0], new->objs[0]);
166 assert_string_equal(orig->objs[0], new->objs[0]);
167
168 /* cleanup */
169 ly_set_free(new, free);
170 ly_set_free(orig, free);
171}
172
173static void
174test_add(void **state)
175{
176 (void) state; /* unused */
177
178 unsigned int u, i;
179 char *str = "test string";
180 struct ly_set set;
181 memset(&set, 0, sizeof set);
182
183 /* add a testing object */
184 assert_int_equal(0, ly_set_add(&set, str, 0));
185
186 /* test avoiding data duplicities */
187 assert_int_equal(0, ly_set_add(&set, str, 0));
188 assert_int_equal(1, set.count);
189 assert_int_equal(1, ly_set_add(&set, str, LY_SET_OPT_USEASLIST));
190 assert_int_equal(2, set.count);
191
192 /* test array resizing */
193 u = set.size;
194 for (i = 2; i <= u; ++i) {
195 assert_int_equal(i, ly_set_add(&set, str, LY_SET_OPT_USEASLIST));
196 }
197 assert_true(u != set.size);
198
199 /* cleanup */
200 ly_set_erase(&set, NULL);
201}
202
203static void
204test_merge(void **state)
205{
206 (void) state; /* unused */
207
208 char *str1, *str2;
209 struct ly_set one, two;
210 memset(&one, 0, sizeof one);
211 memset(&two, 0, sizeof two);
212
213 str1 = strdup("string1");
214 str2 = strdup("string2");
215
216 /* fill first set
217 * - str1 is the same as in two, so it must not be freed! */
218 assert_int_equal(0, ly_set_add(&one, str1, 0));
219
220 /* fill second set */
221 assert_int_equal(0, ly_set_add(&two, str1, 0));
222 assert_int_equal(1, ly_set_add(&two, str2, 0));
223
224 /* merge with checking duplicities - only one item is added into one;
225 * also without duplicating data, so it must not be freed at the end */
226 assert_int_equal(1, ly_set_merge(&one, &two, 0, NULL));
227 assert_ptr_equal(one.objs[1], two.objs[1]);
228
229 /* clean and re-fill one (now duplicating str1, to allow testing duplicator) */
230 ly_set_clean(&one, NULL);
231 assert_int_equal(0, ly_set_add(&one, strdup(str1), 0));
232
233 /* merge without checking duplicities - two items are added into one;
234 * here also with duplicator */
235 assert_int_equal(2, ly_set_merge(&one, &two, LY_SET_OPT_USEASLIST, (void*(*)(void*))strdup));
236 assert_ptr_not_equal(one.objs[1], two.objs[0]);
237 assert_string_equal(one.objs[1], two.objs[0]);
238
239 /* cleanup */
240 ly_set_erase(&one, free);
241 ly_set_erase(&two, free);
242}
243
244static void
245test_rm(void **state)
246{
247 (void) state; /* unused */
248
249 char *str1, *str2, *str3;
250 struct ly_set set;
251 memset(&set, 0, sizeof set);
252
253 /* fill the set */
254 assert_int_equal(0, ly_set_add(&set, "string1", 0));
Radek Krejci820d2262018-09-20 12:15:31 +0200255 assert_int_equal(1, ly_set_add(&set, strdup("string2"), 0));
Radek Krejci519b0432018-09-18 17:04:57 +0200256 assert_int_equal(2, ly_set_add(&set, "string3", 0));
257
258 /* remove by index ... */
259 /* ... in the middle ... */
Radek Krejci820d2262018-09-20 12:15:31 +0200260 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 1, free));
Radek Krejci519b0432018-09-18 17:04:57 +0200261 assert_int_equal(2, set.count);
262 assert_string_not_equal("string2", set.objs[0]);
263 assert_string_not_equal("string2", set.objs[1]);
264 /* ... last .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200265 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 1, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200266 assert_int_equal(1, set.count);
267 assert_string_not_equal("string3", set.objs[0]);
268 /* ... first .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200269 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200270 assert_int_equal(0, set.count);
271
272 /* fill the set */
273 assert_int_equal(0, ly_set_add(&set, str1 = "string1", 0));
274 assert_int_equal(1, ly_set_add(&set, str2 = "string2", 0));
Radek Krejci820d2262018-09-20 12:15:31 +0200275 assert_int_equal(2, ly_set_add(&set, str3 = strdup("string3"), 0));
Radek Krejci519b0432018-09-18 17:04:57 +0200276
277 /* remove by pointer ... */
278 /* ... in the middle ... */
Radek Krejci820d2262018-09-20 12:15:31 +0200279 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str2, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200280 assert_int_equal(2, set.count);
281 assert_string_not_equal("string2", set.objs[0]);
282 assert_string_not_equal("string2", set.objs[1]);
Radek Krejci820d2262018-09-20 12:15:31 +0200283 /* ... last (with destructor) .. */
284 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str3, free));
Radek Krejci519b0432018-09-18 17:04:57 +0200285 assert_int_equal(1, set.count);
286 assert_string_not_equal("string3", set.objs[0]);
287 /* ... first .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200288 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str1, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200289 assert_int_equal(0, set.count);
290
291 /* cleanup */
292 ly_set_erase(&set, NULL);
293}
294
Radek Krejcie84f12f2018-09-18 14:11:50 +0200295int main(void)
296{
297 const struct CMUnitTest tests[] = {
298 cmocka_unit_test(test_basics),
Radek Krejci519b0432018-09-18 17:04:57 +0200299 cmocka_unit_test(test_duplication),
300 cmocka_unit_test(test_add),
301 cmocka_unit_test(test_merge),
302 cmocka_unit_test(test_rm),
Radek Krejcie84f12f2018-09-18 14:11:50 +0200303 cmocka_unit_test_setup(test_inval, logger_setup),
304 };
305
306 return cmocka_run_group_tests(tests, NULL, NULL);
307}