blob: d52ad6ebd739807730e338800e9be65530edcfd8 [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 Krejcif8dc59a2020-11-25 13:47:44 +010016#define _POSIX_C_SOURCE 200809L /* strdup */
Radek Krejcie84f12f2018-09-18 14:11:50 +020017
Radek Krejci535ea9f2020-05-29 16:01:05 +020018#include <stdlib.h>
Radek Krejcie84f12f2018-09-18 14:11:50 +020019#include <string.h>
20
Radek Krejcib4ac5a92020-11-23 17:54:33 +010021#include "utests.h"
Radek Krejci535ea9f2020-05-29 16:01:05 +020022
Radek Krejci70593c12020-06-13 20:48:09 +020023#include "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;
Radek Krejciba03a5a2020-08-27 14:40:41 +020056 uint32_t index;
Radek Krejcie84f12f2018-09-18 14:11:50 +020057
58 /* creation - everything is empty */
Radek Krejciba03a5a2020-08-27 14:40:41 +020059 assert_int_equal(LY_SUCCESS, ly_set_new(&set));
Radek Krejcie84f12f2018-09-18 14:11:50 +020060 assert_non_null(set);
61 assert_int_equal(0, set->count);
62 assert_int_equal(0, set->size);
63 assert_null(set->objs);
64
65 /* add a testing object */
66 str = strdup("test string");
67 assert_non_null(str);
68
Radek Krejciba03a5a2020-08-27 14:40:41 +020069 assert_int_equal(LY_SUCCESS, ly_set_add(set, str, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +020070 assert_int_not_equal(0, set->size);
71 assert_int_equal(1, set->count);
72 assert_non_null(set->objs);
73 assert_non_null(set->objs[0]);
74
75 /* check the presence of the testing data */
Radek Krejciba03a5a2020-08-27 14:40:41 +020076 assert_int_not_equal(0, ly_set_contains(set, str, &index));
77 assert_int_equal(0, index);
78 assert_int_equal(0, ly_set_contains(set, str - 1, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +020079
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;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100102
Radek Krejcie84f12f2018-09-18 14:11:50 +0200103 memset(&set, 0, sizeof set);
104
105 ly_set_clean(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_erase(NULL, NULL);
Radek Krejci0bfec162019-05-02 09:54:25 +0200109 assert_string_equal(logbuf, "");
Radek Krejcie84f12f2018-09-18 14:11:50 +0200110
111 ly_set_free(NULL, NULL);
Radek Krejci0bfec162019-05-02 09:54:25 +0200112 assert_string_equal(logbuf, "");
Radek Krejcie84f12f2018-09-18 14:11:50 +0200113
Radek Krejciba03a5a2020-08-27 14:40:41 +0200114 assert_int_equal(LY_EINVAL, ly_set_dup(NULL, NULL, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200115 assert_string_equal(logbuf, "Invalid argument set (ly_set_dup()).");
116
Radek Krejciba03a5a2020-08-27 14:40:41 +0200117 assert_int_equal(LY_EINVAL, ly_set_add(NULL, NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200118 assert_string_equal(logbuf, "Invalid argument set (ly_set_add()).");
Radek Krejcie84f12f2018-09-18 14:11:50 +0200119
Radek Krejciba03a5a2020-08-27 14:40:41 +0200120 assert_int_equal(LY_EINVAL, ly_set_merge(NULL, NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200121 assert_string_equal(logbuf, "Invalid argument trg (ly_set_merge()).");
Radek Krejciba03a5a2020-08-27 14:40:41 +0200122 assert_int_equal(LY_SUCCESS, ly_set_merge(&set, NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200123
Radek Krejci820d2262018-09-20 12:15:31 +0200124 assert_int_equal(LY_EINVAL, ly_set_rm_index(NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200125 assert_string_equal(logbuf, "Invalid argument set (ly_set_rm_index()).");
Radek Krejci820d2262018-09-20 12:15:31 +0200126 assert_int_equal(LY_EINVAL, ly_set_rm_index(&set, 1, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200127 assert_string_equal(logbuf, "Invalid argument index (ly_set_rm_index()).");
128
Radek Krejci820d2262018-09-20 12:15:31 +0200129 assert_int_equal(LY_EINVAL, ly_set_rm(NULL, NULL, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200130 assert_string_equal(logbuf, "Invalid argument set (ly_set_rm()).");
Radek Krejci820d2262018-09-20 12:15:31 +0200131 assert_int_equal(LY_EINVAL, ly_set_rm(&set, NULL, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200132 assert_string_equal(logbuf, "Invalid argument object (ly_set_rm()).");
Radek Krejci820d2262018-09-20 12:15:31 +0200133 assert_int_equal(LY_EINVAL, ly_set_rm(&set, &state, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200134 assert_string_equal(logbuf, "Invalid argument object (ly_set_rm()).");
135}
136
Radek Krejci519b0432018-09-18 17:04:57 +0200137static void
138test_duplication(void **state)
139{
140 (void) state; /* unused */
141
142 struct ly_set *orig, *new;
143 char *str;
Radek Krejciba03a5a2020-08-27 14:40:41 +0200144 uint32_t index;
Radek Krejci519b0432018-09-18 17:04:57 +0200145
Radek Krejciba03a5a2020-08-27 14:40:41 +0200146 assert_int_equal(LY_SUCCESS, ly_set_new(&orig));
Radek Krejci519b0432018-09-18 17:04:57 +0200147 assert_non_null(orig);
148
149 /* add a testing object */
150 str = strdup("test string");
151 assert_non_null(str);
Radek Krejciba03a5a2020-08-27 14:40:41 +0200152 assert_int_equal(LY_SUCCESS, ly_set_add(orig, str, 0, &index));
153 assert_int_equal(0, index);
Radek Krejci519b0432018-09-18 17:04:57 +0200154
155 /* duplicate the set - without duplicator, so the new set will point to the same string */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200156 assert_int_equal(LY_SUCCESS, ly_set_dup(orig, NULL, &new));
Radek Krejci519b0432018-09-18 17:04:57 +0200157 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 */
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100165 assert_int_equal(LY_SUCCESS, ly_set_dup(orig, (void *(*)(void *))strdup, &new));
Radek Krejci519b0432018-09-18 17:04:57 +0200166 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
Radek Krejciba03a5a2020-08-27 14:40:41 +0200182 uint32_t u, index;
Radek Krejci519b0432018-09-18 17:04:57 +0200183 char *str = "test string";
184 struct ly_set set;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100185
Radek Krejci519b0432018-09-18 17:04:57 +0200186 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 Krejci3d92e442020-10-12 12:48:13 +0200196 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str, 1, &index));
Radek Krejciba03a5a2020-08-27 14:40:41 +0200197 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) {
Radek Krejci3d92e442020-10-12 12:48:13 +0200203 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str, 1, &index));
Radek Krejciba03a5a2020-08-27 14:40:41 +0200204 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;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100219
Radek Krejci519b0432018-09-18 17:04:57 +0200220 memset(&one, 0, sizeof one);
221 memset(&two, 0, sizeof two);
222
223 str1 = strdup("string1");
224 str2 = strdup("string2");
225
226 /* fill first set
227 * - str1 is the same as in two, so it must not be freed! */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200228 assert_int_equal(LY_SUCCESS, ly_set_add(&one, str1, 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200229
230 /* fill second set */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200231 assert_int_equal(LY_SUCCESS, ly_set_add(&two, str1, 0, NULL));
232 assert_int_equal(LY_SUCCESS, ly_set_add(&two, str2, 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200233
234 /* merge with checking duplicities - only one item is added into one;
235 * also without duplicating data, so it must not be freed at the end */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200236 assert_int_equal(LY_SUCCESS, ly_set_merge(&one, &two, 0, NULL));
237 assert_int_equal(2, one.count);
Radek Krejci519b0432018-09-18 17:04:57 +0200238 assert_ptr_equal(one.objs[1], two.objs[1]);
239
240 /* clean and re-fill one (now duplicating str1, to allow testing duplicator) */
241 ly_set_clean(&one, NULL);
Radek Krejciba03a5a2020-08-27 14:40:41 +0200242 assert_int_equal(LY_SUCCESS, ly_set_add(&one, strdup(str1), 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200243
244 /* merge without checking duplicities - two items are added into one;
245 * here also with duplicator */
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100246 assert_int_equal(LY_SUCCESS, ly_set_merge(&one, &two, 1, (void *(*)(void *))strdup));
Radek Krejciba03a5a2020-08-27 14:40:41 +0200247 assert_int_equal(3, one.count);
Radek Krejci519b0432018-09-18 17:04:57 +0200248 assert_ptr_not_equal(one.objs[1], two.objs[0]);
249 assert_string_equal(one.objs[1], two.objs[0]);
250
251 /* cleanup */
252 ly_set_erase(&one, free);
253 ly_set_erase(&two, free);
254}
255
256static void
257test_rm(void **state)
258{
259 (void) state; /* unused */
260
261 char *str1, *str2, *str3;
262 struct ly_set set;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100263
Radek Krejci519b0432018-09-18 17:04:57 +0200264 memset(&set, 0, sizeof set);
265
266 /* fill the set */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200267 assert_int_equal(LY_SUCCESS, ly_set_add(&set, "string1", 0, NULL));
268 assert_int_equal(LY_SUCCESS, ly_set_add(&set, strdup("string2"), 0, NULL));
269 assert_int_equal(LY_SUCCESS, ly_set_add(&set, "string3", 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200270
271 /* remove by index ... */
272 /* ... in the middle ... */
Radek Krejci820d2262018-09-20 12:15:31 +0200273 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 1, free));
Radek Krejci519b0432018-09-18 17:04:57 +0200274 assert_int_equal(2, set.count);
275 assert_string_not_equal("string2", set.objs[0]);
276 assert_string_not_equal("string2", set.objs[1]);
277 /* ... last .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200278 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 1, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200279 assert_int_equal(1, set.count);
280 assert_string_not_equal("string3", set.objs[0]);
281 /* ... first .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200282 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200283 assert_int_equal(0, set.count);
284
285 /* fill the set */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200286 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str1 = "string1", 0, NULL));
287 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str2 = "string2", 0, NULL));
288 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str3 = strdup("string3"), 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200289
290 /* remove by pointer ... */
291 /* ... in the middle ... */
Radek Krejci820d2262018-09-20 12:15:31 +0200292 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str2, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200293 assert_int_equal(2, set.count);
294 assert_string_not_equal("string2", set.objs[0]);
295 assert_string_not_equal("string2", set.objs[1]);
Radek Krejci820d2262018-09-20 12:15:31 +0200296 /* ... last (with destructor) .. */
297 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str3, free));
Radek Krejci519b0432018-09-18 17:04:57 +0200298 assert_int_equal(1, set.count);
299 assert_string_not_equal("string3", set.objs[0]);
300 /* ... first .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200301 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str1, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200302 assert_int_equal(0, set.count);
303
304 /* cleanup */
305 ly_set_erase(&set, NULL);
306}
307
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100308int
309main(void)
Radek Krejcie84f12f2018-09-18 14:11:50 +0200310{
311 const struct CMUnitTest tests[] = {
312 cmocka_unit_test(test_basics),
Radek Krejci519b0432018-09-18 17:04:57 +0200313 cmocka_unit_test(test_duplication),
314 cmocka_unit_test(test_add),
315 cmocka_unit_test(test_merge),
316 cmocka_unit_test(test_rm),
Radek Krejcie84f12f2018-09-18 14:11:50 +0200317 cmocka_unit_test_setup(test_inval, logger_setup),
318 };
319
320 return cmocka_run_group_tests(tests, NULL, NULL);
321}