blob: 4421c3df98203c74f17ef3506104b89b146bf0f3 [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 Krejcie84f12f2018-09-18 14:11:50 +020018#include <stdarg.h>
19#include <stddef.h>
Radek Krejci535ea9f2020-05-29 16:01:05 +020020#include <stdlib.h>
Radek Krejcie84f12f2018-09-18 14:11:50 +020021#include <setjmp.h>
Radek Krejcie84f12f2018-09-18 14:11:50 +020022#include <string.h>
23
Radek Krejci535ea9f2020-05-29 16:01:05 +020024#include <cmocka.h>
25
Radek Krejci70593c12020-06-13 20:48:09 +020026#include "set.h"
Radek Krejcie84f12f2018-09-18 14:11:50 +020027
28#define BUFSIZE 1024
29char logbuf[BUFSIZE] = {0};
30
31static void
32logger(LY_LOG_LEVEL level, const char *msg, const char *path)
33{
34 (void) level; /* unused */
35 (void) path; /* unused */
36
37 strncpy(logbuf, msg, BUFSIZE - 1);
38}
39
40static int
41logger_setup(void **state)
42{
43 (void) state; /* unused */
44
45 ly_set_log_clb(logger, 0);
46
47 return 0;
48}
49
50static void
51test_basics(void **state)
52{
53 (void) state; /* unused */
54
55 struct ly_set *set;
56 char *str;
57 unsigned int u;
58 void *ptr;
Radek Krejciba03a5a2020-08-27 14:40:41 +020059 uint32_t index;
Radek Krejcie84f12f2018-09-18 14:11:50 +020060
61 /* creation - everything is empty */
Radek Krejciba03a5a2020-08-27 14:40:41 +020062 assert_int_equal(LY_SUCCESS, ly_set_new(&set));
Radek Krejcie84f12f2018-09-18 14:11:50 +020063 assert_non_null(set);
64 assert_int_equal(0, set->count);
65 assert_int_equal(0, set->size);
66 assert_null(set->objs);
67
68 /* add a testing object */
69 str = strdup("test string");
70 assert_non_null(str);
71
Radek Krejciba03a5a2020-08-27 14:40:41 +020072 assert_int_equal(LY_SUCCESS, ly_set_add(set, str, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +020073 assert_int_not_equal(0, set->size);
74 assert_int_equal(1, set->count);
75 assert_non_null(set->objs);
76 assert_non_null(set->objs[0]);
77
78 /* check the presence of the testing data */
Radek Krejciba03a5a2020-08-27 14:40:41 +020079 assert_int_not_equal(0, ly_set_contains(set, str, &index));
80 assert_int_equal(0, index);
81 assert_int_equal(0, ly_set_contains(set, str - 1, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +020082
83 /* remove data, but keep the set */
84 u = set->size;
85 ptr = set->objs;
86 ly_set_clean(set, free);
87 assert_int_equal(0, set->count);
88 assert_int_equal(u, set->size);
89 assert_ptr_equal(ptr, set->objs);
90
91 /* remove buffer, but keep the set object */
92 ly_set_erase(set, NULL);
93 assert_int_equal(0, set->count);
94 assert_int_equal(0, set->size);
95 assert_ptr_equal(NULL, set->objs);
96
97 /* final cleanup */
98 ly_set_free(set, NULL);
99}
100
101static void
102test_inval(void **state)
103{
104 struct ly_set set;
105 memset(&set, 0, sizeof set);
106
107 ly_set_clean(NULL, NULL);
Radek Krejci0bfec162019-05-02 09:54:25 +0200108 assert_string_equal(logbuf, "");
Radek Krejcie84f12f2018-09-18 14:11:50 +0200109
110 ly_set_erase(NULL, NULL);
Radek Krejci0bfec162019-05-02 09:54:25 +0200111 assert_string_equal(logbuf, "");
Radek Krejcie84f12f2018-09-18 14:11:50 +0200112
113 ly_set_free(NULL, NULL);
Radek Krejci0bfec162019-05-02 09:54:25 +0200114 assert_string_equal(logbuf, "");
Radek Krejcie84f12f2018-09-18 14:11:50 +0200115
Radek Krejciba03a5a2020-08-27 14:40:41 +0200116 assert_int_equal(LY_EINVAL, ly_set_dup(NULL, NULL, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200117 assert_string_equal(logbuf, "Invalid argument set (ly_set_dup()).");
118
Radek Krejciba03a5a2020-08-27 14:40:41 +0200119 assert_int_equal(LY_EINVAL, ly_set_add(NULL, NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200120 assert_string_equal(logbuf, "Invalid argument set (ly_set_add()).");
Radek Krejcie84f12f2018-09-18 14:11:50 +0200121
Radek Krejciba03a5a2020-08-27 14:40:41 +0200122 assert_int_equal(LY_EINVAL, ly_set_merge(NULL, NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200123 assert_string_equal(logbuf, "Invalid argument trg (ly_set_merge()).");
Radek Krejciba03a5a2020-08-27 14:40:41 +0200124 assert_int_equal(LY_SUCCESS, ly_set_merge(&set, NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +0200125
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;
Radek Krejciba03a5a2020-08-27 14:40:41 +0200146 uint32_t index;
Radek Krejci519b0432018-09-18 17:04:57 +0200147
Radek Krejciba03a5a2020-08-27 14:40:41 +0200148 assert_int_equal(LY_SUCCESS, ly_set_new(&orig));
Radek Krejci519b0432018-09-18 17:04:57 +0200149 assert_non_null(orig);
150
151 /* add a testing object */
152 str = strdup("test string");
153 assert_non_null(str);
Radek Krejciba03a5a2020-08-27 14:40:41 +0200154 assert_int_equal(LY_SUCCESS, ly_set_add(orig, str, 0, &index));
155 assert_int_equal(0, index);
Radek Krejci519b0432018-09-18 17:04:57 +0200156
157 /* duplicate the set - without duplicator, so the new set will point to the same string */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200158 assert_int_equal(LY_SUCCESS, ly_set_dup(orig, NULL, &new));
Radek Krejci519b0432018-09-18 17:04:57 +0200159 assert_non_null(new);
160 assert_ptr_not_equal(orig, new);
161 assert_int_equal(orig->count, new->count);
162 assert_ptr_equal(orig->objs[0], new->objs[0]);
163
164 ly_set_free(new, NULL);
165
166 /* 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 +0200167 assert_int_equal(LY_SUCCESS, ly_set_dup(orig, (void*(*)(void*))strdup, &new));
Radek Krejci519b0432018-09-18 17:04:57 +0200168 assert_non_null(new);
169 assert_ptr_not_equal(orig, new);
170 assert_int_equal(orig->count, new->count);
171 assert_ptr_not_equal(orig->objs[0], new->objs[0]);
172 assert_string_equal(orig->objs[0], new->objs[0]);
173
174 /* cleanup */
175 ly_set_free(new, free);
176 ly_set_free(orig, free);
177}
178
179static void
180test_add(void **state)
181{
182 (void) state; /* unused */
183
Radek Krejciba03a5a2020-08-27 14:40:41 +0200184 uint32_t u, index;
Radek Krejci519b0432018-09-18 17:04:57 +0200185 char *str = "test string";
186 struct ly_set set;
187 memset(&set, 0, sizeof set);
188
189 /* add a testing object */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200190 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str, 0, &index));
191 assert_int_equal(0, index);
Radek Krejci519b0432018-09-18 17:04:57 +0200192
193 /* test avoiding data duplicities */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200194 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str, 0, &index));
195 assert_int_equal(0, index);
Radek Krejci519b0432018-09-18 17:04:57 +0200196 assert_int_equal(1, set.count);
Radek Krejci3d92e442020-10-12 12:48:13 +0200197 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str, 1, &index));
Radek Krejciba03a5a2020-08-27 14:40:41 +0200198 assert_int_equal(1, index);
Radek Krejci519b0432018-09-18 17:04:57 +0200199 assert_int_equal(2, set.count);
200
201 /* test array resizing */
202 u = set.size;
Radek Krejciba03a5a2020-08-27 14:40:41 +0200203 for (uint32_t expected_index = 2; expected_index <= u; ++expected_index) {
Radek Krejci3d92e442020-10-12 12:48:13 +0200204 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str, 1, &index));
Radek Krejciba03a5a2020-08-27 14:40:41 +0200205 assert_int_equal(expected_index, index);
Radek Krejci519b0432018-09-18 17:04:57 +0200206 }
207 assert_true(u != set.size);
208
209 /* cleanup */
210 ly_set_erase(&set, NULL);
211}
212
213static void
214test_merge(void **state)
215{
216 (void) state; /* unused */
217
218 char *str1, *str2;
219 struct ly_set one, two;
220 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 Krejci3d92e442020-10-12 12:48:13 +0200246 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;
263 memset(&set, 0, sizeof set);
264
265 /* fill the set */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200266 assert_int_equal(LY_SUCCESS, ly_set_add(&set, "string1", 0, NULL));
267 assert_int_equal(LY_SUCCESS, ly_set_add(&set, strdup("string2"), 0, NULL));
268 assert_int_equal(LY_SUCCESS, ly_set_add(&set, "string3", 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200269
270 /* remove by index ... */
271 /* ... in the middle ... */
Radek Krejci820d2262018-09-20 12:15:31 +0200272 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 1, free));
Radek Krejci519b0432018-09-18 17:04:57 +0200273 assert_int_equal(2, set.count);
274 assert_string_not_equal("string2", set.objs[0]);
275 assert_string_not_equal("string2", set.objs[1]);
276 /* ... last .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200277 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 1, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200278 assert_int_equal(1, set.count);
279 assert_string_not_equal("string3", set.objs[0]);
280 /* ... first .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200281 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200282 assert_int_equal(0, set.count);
283
284 /* fill the set */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200285 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str1 = "string1", 0, NULL));
286 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str2 = "string2", 0, NULL));
287 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str3 = strdup("string3"), 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200288
289 /* remove by pointer ... */
290 /* ... in the middle ... */
Radek Krejci820d2262018-09-20 12:15:31 +0200291 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str2, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200292 assert_int_equal(2, set.count);
293 assert_string_not_equal("string2", set.objs[0]);
294 assert_string_not_equal("string2", set.objs[1]);
Radek Krejci820d2262018-09-20 12:15:31 +0200295 /* ... last (with destructor) .. */
296 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str3, free));
Radek Krejci519b0432018-09-18 17:04:57 +0200297 assert_int_equal(1, set.count);
298 assert_string_not_equal("string3", set.objs[0]);
299 /* ... first .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200300 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str1, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200301 assert_int_equal(0, set.count);
302
303 /* cleanup */
304 ly_set_erase(&set, NULL);
305}
306
Radek Krejcie84f12f2018-09-18 14:11:50 +0200307int main(void)
308{
309 const struct CMUnitTest tests[] = {
310 cmocka_unit_test(test_basics),
Radek Krejci519b0432018-09-18 17:04:57 +0200311 cmocka_unit_test(test_duplication),
312 cmocka_unit_test(test_add),
313 cmocka_unit_test(test_merge),
314 cmocka_unit_test(test_rm),
Radek Krejcie84f12f2018-09-18 14:11:50 +0200315 cmocka_unit_test_setup(test_inval, logger_setup),
316 };
317
318 return cmocka_run_group_tests(tests, NULL, NULL);
319}