blob: ba45776cc0ea5a57fa8644e7df48780f7cfa6dd8 [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 Krejci535ea9f2020-05-29 16:01:05 +020014
15#define _GNU_SOURCE
Radek Krejcie84f12f2018-09-18 14:11:50 +020016
Radek Krejcie84f12f2018-09-18 14:11:50 +020017#include <stdarg.h>
18#include <stddef.h>
Radek Krejci535ea9f2020-05-29 16:01:05 +020019#include <stdlib.h>
Radek Krejcie84f12f2018-09-18 14:11:50 +020020#include <setjmp.h>
Radek Krejcie84f12f2018-09-18 14:11:50 +020021#include <string.h>
22
Radek Krejci535ea9f2020-05-29 16:01:05 +020023#include <cmocka.h>
24
Radek Krejci70593c12020-06-13 20:48:09 +020025#include "set.h"
Radek Krejcie84f12f2018-09-18 14:11:50 +020026
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;
Radek Krejciba03a5a2020-08-27 14:40:41 +020058 uint32_t index;
Radek Krejcie84f12f2018-09-18 14:11:50 +020059
60 /* creation - everything is empty */
Radek Krejciba03a5a2020-08-27 14:40:41 +020061 assert_int_equal(LY_SUCCESS, ly_set_new(&set));
Radek Krejcie84f12f2018-09-18 14:11:50 +020062 assert_non_null(set);
63 assert_int_equal(0, set->count);
64 assert_int_equal(0, set->size);
65 assert_null(set->objs);
66
67 /* add a testing object */
68 str = strdup("test string");
69 assert_non_null(str);
70
Radek Krejciba03a5a2020-08-27 14:40:41 +020071 assert_int_equal(LY_SUCCESS, ly_set_add(set, str, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +020072 assert_int_not_equal(0, set->size);
73 assert_int_equal(1, set->count);
74 assert_non_null(set->objs);
75 assert_non_null(set->objs[0]);
76
77 /* check the presence of the testing data */
Radek Krejciba03a5a2020-08-27 14:40:41 +020078 assert_int_not_equal(0, ly_set_contains(set, str, &index));
79 assert_int_equal(0, index);
80 assert_int_equal(0, ly_set_contains(set, str - 1, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +020081
82 /* remove data, but keep the set */
83 u = set->size;
84 ptr = set->objs;
85 ly_set_clean(set, free);
86 assert_int_equal(0, set->count);
87 assert_int_equal(u, set->size);
88 assert_ptr_equal(ptr, set->objs);
89
90 /* remove buffer, but keep the set object */
91 ly_set_erase(set, NULL);
92 assert_int_equal(0, set->count);
93 assert_int_equal(0, set->size);
94 assert_ptr_equal(NULL, set->objs);
95
96 /* final cleanup */
97 ly_set_free(set, NULL);
98}
99
100static void
101test_inval(void **state)
102{
103 struct ly_set set;
104 memset(&set, 0, sizeof set);
105
106 ly_set_clean(NULL, NULL);
Radek Krejci0bfec162019-05-02 09:54:25 +0200107 assert_string_equal(logbuf, "");
Radek Krejcie84f12f2018-09-18 14:11:50 +0200108
109 ly_set_erase(NULL, NULL);
Radek Krejci0bfec162019-05-02 09:54:25 +0200110 assert_string_equal(logbuf, "");
Radek Krejcie84f12f2018-09-18 14:11:50 +0200111
112 ly_set_free(NULL, NULL);
Radek Krejci0bfec162019-05-02 09:54:25 +0200113 assert_string_equal(logbuf, "");
Radek Krejcie84f12f2018-09-18 14:11:50 +0200114
Radek Krejciba03a5a2020-08-27 14:40:41 +0200115 assert_int_equal(LY_EINVAL, ly_set_dup(NULL, NULL, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200116 assert_string_equal(logbuf, "Invalid argument set (ly_set_dup()).");
117
Radek Krejciba03a5a2020-08-27 14:40:41 +0200118 assert_int_equal(LY_EINVAL, ly_set_add(NULL, NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200119 assert_string_equal(logbuf, "Invalid argument set (ly_set_add()).");
Radek Krejcie84f12f2018-09-18 14:11:50 +0200120
Radek Krejciba03a5a2020-08-27 14:40:41 +0200121 assert_int_equal(LY_EINVAL, 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 Krejciba03a5a2020-08-27 14:40:41 +0200123 assert_int_equal(LY_SUCCESS, ly_set_merge(&set, NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200124
Radek Krejci820d2262018-09-20 12:15:31 +0200125 assert_int_equal(LY_EINVAL, ly_set_rm_index(NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200126 assert_string_equal(logbuf, "Invalid argument set (ly_set_rm_index()).");
Radek Krejci820d2262018-09-20 12:15:31 +0200127 assert_int_equal(LY_EINVAL, ly_set_rm_index(&set, 1, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200128 assert_string_equal(logbuf, "Invalid argument index (ly_set_rm_index()).");
129
Radek Krejci820d2262018-09-20 12:15:31 +0200130 assert_int_equal(LY_EINVAL, ly_set_rm(NULL, NULL, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200131 assert_string_equal(logbuf, "Invalid argument set (ly_set_rm()).");
Radek Krejci820d2262018-09-20 12:15:31 +0200132 assert_int_equal(LY_EINVAL, ly_set_rm(&set, NULL, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200133 assert_string_equal(logbuf, "Invalid argument object (ly_set_rm()).");
Radek Krejci820d2262018-09-20 12:15:31 +0200134 assert_int_equal(LY_EINVAL, ly_set_rm(&set, &state, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200135 assert_string_equal(logbuf, "Invalid argument object (ly_set_rm()).");
136}
137
Radek Krejci519b0432018-09-18 17:04:57 +0200138static void
139test_duplication(void **state)
140{
141 (void) state; /* unused */
142
143 struct ly_set *orig, *new;
144 char *str;
Radek Krejciba03a5a2020-08-27 14:40:41 +0200145 uint32_t index;
Radek Krejci519b0432018-09-18 17:04:57 +0200146
Radek Krejciba03a5a2020-08-27 14:40:41 +0200147 assert_int_equal(LY_SUCCESS, ly_set_new(&orig));
Radek Krejci519b0432018-09-18 17:04:57 +0200148 assert_non_null(orig);
149
150 /* add a testing object */
151 str = strdup("test string");
152 assert_non_null(str);
Radek Krejciba03a5a2020-08-27 14:40:41 +0200153 assert_int_equal(LY_SUCCESS, ly_set_add(orig, str, 0, &index));
154 assert_int_equal(0, index);
Radek Krejci519b0432018-09-18 17:04:57 +0200155
156 /* duplicate the set - without duplicator, so the new set will point to the same string */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200157 assert_int_equal(LY_SUCCESS, ly_set_dup(orig, NULL, &new));
Radek Krejci519b0432018-09-18 17:04:57 +0200158 assert_non_null(new);
159 assert_ptr_not_equal(orig, new);
160 assert_int_equal(orig->count, new->count);
161 assert_ptr_equal(orig->objs[0], new->objs[0]);
162
163 ly_set_free(new, NULL);
164
165 /* duplicate the set - with duplicator, so the new set will point to a different buffer with the same content */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200166 assert_int_equal(LY_SUCCESS, ly_set_dup(orig, (void*(*)(void*))strdup, &new));
Radek Krejci519b0432018-09-18 17:04:57 +0200167 assert_non_null(new);
168 assert_ptr_not_equal(orig, new);
169 assert_int_equal(orig->count, new->count);
170 assert_ptr_not_equal(orig->objs[0], new->objs[0]);
171 assert_string_equal(orig->objs[0], new->objs[0]);
172
173 /* cleanup */
174 ly_set_free(new, free);
175 ly_set_free(orig, free);
176}
177
178static void
179test_add(void **state)
180{
181 (void) state; /* unused */
182
Radek Krejciba03a5a2020-08-27 14:40:41 +0200183 uint32_t u, index;
Radek Krejci519b0432018-09-18 17:04:57 +0200184 char *str = "test string";
185 struct ly_set set;
186 memset(&set, 0, sizeof set);
187
188 /* add a testing object */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200189 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str, 0, &index));
190 assert_int_equal(0, index);
Radek Krejci519b0432018-09-18 17:04:57 +0200191
192 /* test avoiding data duplicities */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200193 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str, 0, &index));
194 assert_int_equal(0, index);
Radek Krejci519b0432018-09-18 17:04:57 +0200195 assert_int_equal(1, set.count);
Radek Krejciba03a5a2020-08-27 14:40:41 +0200196 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str, LY_SET_OPT_USEASLIST, &index));
197 assert_int_equal(1, index);
Radek Krejci519b0432018-09-18 17:04:57 +0200198 assert_int_equal(2, set.count);
199
200 /* test array resizing */
201 u = set.size;
Radek Krejciba03a5a2020-08-27 14:40:41 +0200202 for (uint32_t expected_index = 2; expected_index <= u; ++expected_index) {
203 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str, LY_SET_OPT_USEASLIST, &index));
204 assert_int_equal(expected_index, index);
Radek Krejci519b0432018-09-18 17:04:57 +0200205 }
206 assert_true(u != set.size);
207
208 /* cleanup */
209 ly_set_erase(&set, NULL);
210}
211
212static void
213test_merge(void **state)
214{
215 (void) state; /* unused */
216
217 char *str1, *str2;
218 struct ly_set one, two;
219 memset(&one, 0, sizeof one);
220 memset(&two, 0, sizeof two);
221
222 str1 = strdup("string1");
223 str2 = strdup("string2");
224
225 /* fill first set
226 * - str1 is the same as in two, so it must not be freed! */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200227 assert_int_equal(LY_SUCCESS, ly_set_add(&one, str1, 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200228
229 /* fill second set */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200230 assert_int_equal(LY_SUCCESS, ly_set_add(&two, str1, 0, NULL));
231 assert_int_equal(LY_SUCCESS, ly_set_add(&two, str2, 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200232
233 /* merge with checking duplicities - only one item is added into one;
234 * also without duplicating data, so it must not be freed at the end */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200235 assert_int_equal(LY_SUCCESS, ly_set_merge(&one, &two, 0, NULL));
236 assert_int_equal(2, one.count);
Radek Krejci519b0432018-09-18 17:04:57 +0200237 assert_ptr_equal(one.objs[1], two.objs[1]);
238
239 /* clean and re-fill one (now duplicating str1, to allow testing duplicator) */
240 ly_set_clean(&one, NULL);
Radek Krejciba03a5a2020-08-27 14:40:41 +0200241 assert_int_equal(LY_SUCCESS, ly_set_add(&one, strdup(str1), 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200242
243 /* merge without checking duplicities - two items are added into one;
244 * here also with duplicator */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200245 assert_int_equal(LY_SUCCESS, ly_set_merge(&one, &two, LY_SET_OPT_USEASLIST, (void*(*)(void*))strdup));
246 assert_int_equal(3, one.count);
Radek Krejci519b0432018-09-18 17:04:57 +0200247 assert_ptr_not_equal(one.objs[1], two.objs[0]);
248 assert_string_equal(one.objs[1], two.objs[0]);
249
250 /* cleanup */
251 ly_set_erase(&one, free);
252 ly_set_erase(&two, free);
253}
254
255static void
256test_rm(void **state)
257{
258 (void) state; /* unused */
259
260 char *str1, *str2, *str3;
261 struct ly_set set;
262 memset(&set, 0, sizeof set);
263
264 /* fill the set */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200265 assert_int_equal(LY_SUCCESS, ly_set_add(&set, "string1", 0, NULL));
266 assert_int_equal(LY_SUCCESS, ly_set_add(&set, strdup("string2"), 0, NULL));
267 assert_int_equal(LY_SUCCESS, ly_set_add(&set, "string3", 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200268
269 /* remove by index ... */
270 /* ... in the middle ... */
Radek Krejci820d2262018-09-20 12:15:31 +0200271 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 1, free));
Radek Krejci519b0432018-09-18 17:04:57 +0200272 assert_int_equal(2, set.count);
273 assert_string_not_equal("string2", set.objs[0]);
274 assert_string_not_equal("string2", set.objs[1]);
275 /* ... last .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200276 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 1, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200277 assert_int_equal(1, set.count);
278 assert_string_not_equal("string3", set.objs[0]);
279 /* ... first .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200280 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200281 assert_int_equal(0, set.count);
282
283 /* fill the set */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200284 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str1 = "string1", 0, NULL));
285 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str2 = "string2", 0, NULL));
286 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str3 = strdup("string3"), 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200287
288 /* remove by pointer ... */
289 /* ... in the middle ... */
Radek Krejci820d2262018-09-20 12:15:31 +0200290 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str2, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200291 assert_int_equal(2, set.count);
292 assert_string_not_equal("string2", set.objs[0]);
293 assert_string_not_equal("string2", set.objs[1]);
Radek Krejci820d2262018-09-20 12:15:31 +0200294 /* ... last (with destructor) .. */
295 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str3, free));
Radek Krejci519b0432018-09-18 17:04:57 +0200296 assert_int_equal(1, set.count);
297 assert_string_not_equal("string3", set.objs[0]);
298 /* ... first .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200299 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str1, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200300 assert_int_equal(0, set.count);
301
302 /* cleanup */
303 ly_set_erase(&set, NULL);
304}
305
Radek Krejcie84f12f2018-09-18 14:11:50 +0200306int main(void)
307{
308 const struct CMUnitTest tests[] = {
309 cmocka_unit_test(test_basics),
Radek Krejci519b0432018-09-18 17:04:57 +0200310 cmocka_unit_test(test_duplication),
311 cmocka_unit_test(test_add),
312 cmocka_unit_test(test_merge),
313 cmocka_unit_test(test_rm),
Radek Krejcie84f12f2018-09-18 14:11:50 +0200314 cmocka_unit_test_setup(test_inval, logger_setup),
315 };
316
317 return cmocka_run_group_tests(tests, NULL, NULL);
318}