blob: 04ea6bc4e92de2ba76bde2a6bdc3adb4504de0bb [file] [log] [blame]
Michal Vaskof20ad112023-02-10 15:12:12 +01001/**
aPiecek023f83a2021-05-11 07:37:03 +02002 * @file test_set.c
Radek Krejcie84f12f2018-09-18 14:11:50 +02003 * @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 Krejcif8dc59a2020-11-25 13:47:44 +010014#define _POSIX_C_SOURCE 200809L /* strdup */
Radek Iša56ca9e42020-09-08 18:42:00 +020015#define _UTEST_MAIN_
16#include "utests.h"
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 Krejci70593c12020-06-13 20:48:09 +020021#include "set.h"
Radek Krejcie84f12f2018-09-18 14:11:50 +020022
Radek Krejcie84f12f2018-09-18 14:11:50 +020023static void
Radek Iša56ca9e42020-09-08 18:42:00 +020024test_basics(void **UNUSED(state))
Radek Krejcie84f12f2018-09-18 14:11:50 +020025{
Radek Krejcie84f12f2018-09-18 14:11:50 +020026 struct ly_set *set;
27 char *str;
28 unsigned int u;
29 void *ptr;
Radek Krejciba03a5a2020-08-27 14:40:41 +020030 uint32_t index;
Radek Krejcie84f12f2018-09-18 14:11:50 +020031
32 /* creation - everything is empty */
Radek Krejciba03a5a2020-08-27 14:40:41 +020033 assert_int_equal(LY_SUCCESS, ly_set_new(&set));
Radek Krejcie84f12f2018-09-18 14:11:50 +020034 assert_non_null(set);
35 assert_int_equal(0, set->count);
36 assert_int_equal(0, set->size);
37 assert_null(set->objs);
38
39 /* add a testing object */
40 str = strdup("test string");
41 assert_non_null(str);
42
Radek Krejciba03a5a2020-08-27 14:40:41 +020043 assert_int_equal(LY_SUCCESS, ly_set_add(set, str, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +020044 assert_int_not_equal(0, set->size);
45 assert_int_equal(1, set->count);
46 assert_non_null(set->objs);
47 assert_non_null(set->objs[0]);
48
49 /* check the presence of the testing data */
Michal Vaskof9c0a672022-02-17 10:48:14 +010050 assert_int_equal(1, ly_set_contains(set, str, &index));
Radek Krejciba03a5a2020-08-27 14:40:41 +020051 assert_int_equal(0, index);
52 assert_int_equal(0, ly_set_contains(set, str - 1, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +020053
54 /* remove data, but keep the set */
55 u = set->size;
56 ptr = set->objs;
57 ly_set_clean(set, free);
58 assert_int_equal(0, set->count);
59 assert_int_equal(u, set->size);
60 assert_ptr_equal(ptr, set->objs);
61
62 /* remove buffer, but keep the set object */
63 ly_set_erase(set, NULL);
64 assert_int_equal(0, set->count);
65 assert_int_equal(0, set->size);
66 assert_ptr_equal(NULL, set->objs);
67
68 /* final cleanup */
69 ly_set_free(set, NULL);
70}
71
72static void
Michal Vasko7a266772024-01-23 11:02:38 +010073test_inval(void **UNUSED(state))
Radek Krejcie84f12f2018-09-18 14:11:50 +020074{
Michal Vasko7a266772024-01-23 11:02:38 +010075 struct ly_set set = {0};
Radek Krejcie84f12f2018-09-18 14:11:50 +020076
Radek Krejciba03a5a2020-08-27 14:40:41 +020077 assert_int_equal(LY_EINVAL, ly_set_dup(NULL, NULL, NULL));
Michal Vasko7a266772024-01-23 11:02:38 +010078 CHECK_LOG_LASTMSG("Invalid argument set (ly_set_dup()).");
Radek Krejcie84f12f2018-09-18 14:11:50 +020079
Radek Krejciba03a5a2020-08-27 14:40:41 +020080 assert_int_equal(LY_EINVAL, ly_set_add(NULL, NULL, 0, NULL));
Michal Vasko7a266772024-01-23 11:02:38 +010081 CHECK_LOG_LASTMSG("Invalid argument set (ly_set_add()).");
Radek Krejcie84f12f2018-09-18 14:11:50 +020082
Radek Krejciba03a5a2020-08-27 14:40:41 +020083 assert_int_equal(LY_EINVAL, ly_set_merge(NULL, NULL, 0, NULL));
Michal Vasko7a266772024-01-23 11:02:38 +010084 CHECK_LOG_LASTMSG("Invalid argument trg (ly_set_merge()).");
Radek Krejciba03a5a2020-08-27 14:40:41 +020085 assert_int_equal(LY_SUCCESS, ly_set_merge(&set, NULL, 0, NULL));
Radek Krejcie84f12f2018-09-18 14:11:50 +020086
Radek Krejci820d2262018-09-20 12:15:31 +020087 assert_int_equal(LY_EINVAL, ly_set_rm_index(NULL, 0, NULL));
Michal Vasko7a266772024-01-23 11:02:38 +010088 CHECK_LOG_LASTMSG("Invalid argument set (ly_set_rm_index()).");
Radek Krejci820d2262018-09-20 12:15:31 +020089 assert_int_equal(LY_EINVAL, ly_set_rm_index(&set, 1, NULL));
Michal Vasko7a266772024-01-23 11:02:38 +010090 CHECK_LOG_LASTMSG("Invalid argument index (ly_set_rm_index()).");
Radek Krejcie84f12f2018-09-18 14:11:50 +020091
Radek Krejci820d2262018-09-20 12:15:31 +020092 assert_int_equal(LY_EINVAL, ly_set_rm(NULL, NULL, NULL));
Michal Vasko7a266772024-01-23 11:02:38 +010093 CHECK_LOG_LASTMSG("Invalid argument set (ly_set_rm()).");
Radek Krejci820d2262018-09-20 12:15:31 +020094 assert_int_equal(LY_EINVAL, ly_set_rm(&set, NULL, NULL));
Michal Vasko7a266772024-01-23 11:02:38 +010095 CHECK_LOG_LASTMSG("Invalid argument object (ly_set_rm()).");
Radek Iša56ca9e42020-09-08 18:42:00 +020096 assert_int_equal(LY_EINVAL, ly_set_rm(&set, &set, NULL));
Michal Vasko7a266772024-01-23 11:02:38 +010097 CHECK_LOG_LASTMSG("Invalid argument object (ly_set_rm()).");
Radek Krejcie84f12f2018-09-18 14:11:50 +020098}
99
Radek Krejci519b0432018-09-18 17:04:57 +0200100static void
Radek Iša56ca9e42020-09-08 18:42:00 +0200101test_duplication(void **UNUSED(state))
Radek Krejci519b0432018-09-18 17:04:57 +0200102{
Radek Krejci519b0432018-09-18 17:04:57 +0200103 struct ly_set *orig, *new;
104 char *str;
Radek Krejciba03a5a2020-08-27 14:40:41 +0200105 uint32_t index;
Radek Krejci519b0432018-09-18 17:04:57 +0200106
Radek Krejciba03a5a2020-08-27 14:40:41 +0200107 assert_int_equal(LY_SUCCESS, ly_set_new(&orig));
Radek Krejci519b0432018-09-18 17:04:57 +0200108 assert_non_null(orig);
109
110 /* add a testing object */
111 str = strdup("test string");
112 assert_non_null(str);
Radek Krejciba03a5a2020-08-27 14:40:41 +0200113 assert_int_equal(LY_SUCCESS, ly_set_add(orig, str, 0, &index));
114 assert_int_equal(0, index);
Radek Krejci519b0432018-09-18 17:04:57 +0200115
116 /* duplicate the set - without duplicator, so the new set will point to the same string */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200117 assert_int_equal(LY_SUCCESS, ly_set_dup(orig, NULL, &new));
Radek Krejci519b0432018-09-18 17:04:57 +0200118 assert_non_null(new);
119 assert_ptr_not_equal(orig, new);
120 assert_int_equal(orig->count, new->count);
121 assert_ptr_equal(orig->objs[0], new->objs[0]);
122
123 ly_set_free(new, NULL);
124
125 /* duplicate the set - with duplicator, so the new set will point to a different buffer with the same content */
Michal Vasko193dacd2022-10-13 08:43:05 +0200126 assert_int_equal(LY_SUCCESS, ly_set_dup(orig, (void *(*)(const void *))strdup, &new));
Radek Krejci519b0432018-09-18 17:04:57 +0200127 assert_non_null(new);
128 assert_ptr_not_equal(orig, new);
129 assert_int_equal(orig->count, new->count);
130 assert_ptr_not_equal(orig->objs[0], new->objs[0]);
131 assert_string_equal(orig->objs[0], new->objs[0]);
132
133 /* cleanup */
134 ly_set_free(new, free);
135 ly_set_free(orig, free);
136}
137
138static void
Radek Iša56ca9e42020-09-08 18:42:00 +0200139test_add(void **UNUSED(state))
Radek Krejci519b0432018-09-18 17:04:57 +0200140{
Radek Krejciba03a5a2020-08-27 14:40:41 +0200141 uint32_t u, index;
Radek Krejci519b0432018-09-18 17:04:57 +0200142 char *str = "test string";
143 struct ly_set set;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100144
Radek Krejci519b0432018-09-18 17:04:57 +0200145 memset(&set, 0, sizeof set);
146
147 /* add a testing object */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200148 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str, 0, &index));
149 assert_int_equal(0, index);
Radek Krejci519b0432018-09-18 17:04:57 +0200150
151 /* test avoiding data duplicities */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200152 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str, 0, &index));
153 assert_int_equal(0, index);
Radek Krejci519b0432018-09-18 17:04:57 +0200154 assert_int_equal(1, set.count);
Radek Krejci3d92e442020-10-12 12:48:13 +0200155 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str, 1, &index));
Radek Krejciba03a5a2020-08-27 14:40:41 +0200156 assert_int_equal(1, index);
Radek Krejci519b0432018-09-18 17:04:57 +0200157 assert_int_equal(2, set.count);
158
159 /* test array resizing */
160 u = set.size;
Radek Krejciba03a5a2020-08-27 14:40:41 +0200161 for (uint32_t expected_index = 2; expected_index <= u; ++expected_index) {
Radek Krejci3d92e442020-10-12 12:48:13 +0200162 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str, 1, &index));
Radek Krejciba03a5a2020-08-27 14:40:41 +0200163 assert_int_equal(expected_index, index);
Radek Krejci519b0432018-09-18 17:04:57 +0200164 }
165 assert_true(u != set.size);
166
167 /* cleanup */
168 ly_set_erase(&set, NULL);
169}
170
171static void
Radek Iša56ca9e42020-09-08 18:42:00 +0200172test_merge(void **UNUSED(state))
Radek Krejci519b0432018-09-18 17:04:57 +0200173{
Radek Krejci519b0432018-09-18 17:04:57 +0200174 char *str1, *str2;
175 struct ly_set one, two;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100176
Radek Krejci519b0432018-09-18 17:04:57 +0200177 memset(&one, 0, sizeof one);
178 memset(&two, 0, sizeof two);
179
180 str1 = strdup("string1");
181 str2 = strdup("string2");
182
183 /* fill first set
184 * - str1 is the same as in two, so it must not be freed! */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200185 assert_int_equal(LY_SUCCESS, ly_set_add(&one, str1, 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200186
187 /* fill second set */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200188 assert_int_equal(LY_SUCCESS, ly_set_add(&two, str1, 0, NULL));
189 assert_int_equal(LY_SUCCESS, ly_set_add(&two, str2, 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200190
191 /* merge with checking duplicities - only one item is added into one;
192 * also without duplicating data, so it must not be freed at the end */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200193 assert_int_equal(LY_SUCCESS, ly_set_merge(&one, &two, 0, NULL));
194 assert_int_equal(2, one.count);
Radek Krejci519b0432018-09-18 17:04:57 +0200195 assert_ptr_equal(one.objs[1], two.objs[1]);
196
197 /* clean and re-fill one (now duplicating str1, to allow testing duplicator) */
198 ly_set_clean(&one, NULL);
Radek Krejciba03a5a2020-08-27 14:40:41 +0200199 assert_int_equal(LY_SUCCESS, ly_set_add(&one, strdup(str1), 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200200
201 /* merge without checking duplicities - two items are added into one;
202 * here also with duplicator */
Michal Vasko193dacd2022-10-13 08:43:05 +0200203 assert_int_equal(LY_SUCCESS, ly_set_merge(&one, &two, 1, (void *(*)(const void *))strdup));
Radek Krejciba03a5a2020-08-27 14:40:41 +0200204 assert_int_equal(3, one.count);
Radek Krejci519b0432018-09-18 17:04:57 +0200205 assert_ptr_not_equal(one.objs[1], two.objs[0]);
206 assert_string_equal(one.objs[1], two.objs[0]);
207
208 /* cleanup */
209 ly_set_erase(&one, free);
210 ly_set_erase(&two, free);
211}
212
213static void
Radek Iša56ca9e42020-09-08 18:42:00 +0200214test_rm(void **UNUSED(state))
Radek Krejci519b0432018-09-18 17:04:57 +0200215{
Radek Krejci519b0432018-09-18 17:04:57 +0200216 char *str1, *str2, *str3;
217 struct ly_set set;
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100218
Radek Krejci519b0432018-09-18 17:04:57 +0200219 memset(&set, 0, sizeof set);
220
221 /* fill the set */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200222 assert_int_equal(LY_SUCCESS, ly_set_add(&set, "string1", 0, NULL));
223 assert_int_equal(LY_SUCCESS, ly_set_add(&set, strdup("string2"), 0, NULL));
224 assert_int_equal(LY_SUCCESS, ly_set_add(&set, "string3", 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200225
226 /* remove by index ... */
227 /* ... in the middle ... */
Radek Krejci820d2262018-09-20 12:15:31 +0200228 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 1, free));
Radek Krejci519b0432018-09-18 17:04:57 +0200229 assert_int_equal(2, set.count);
230 assert_string_not_equal("string2", set.objs[0]);
231 assert_string_not_equal("string2", set.objs[1]);
232 /* ... last .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200233 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 1, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200234 assert_int_equal(1, set.count);
235 assert_string_not_equal("string3", set.objs[0]);
236 /* ... first .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200237 assert_int_equal(LY_SUCCESS, ly_set_rm_index(&set, 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200238 assert_int_equal(0, set.count);
239
240 /* fill the set */
Radek Krejciba03a5a2020-08-27 14:40:41 +0200241 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str1 = "string1", 0, NULL));
242 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str2 = "string2", 0, NULL));
243 assert_int_equal(LY_SUCCESS, ly_set_add(&set, str3 = strdup("string3"), 0, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200244
245 /* remove by pointer ... */
246 /* ... in the middle ... */
Radek Krejci820d2262018-09-20 12:15:31 +0200247 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str2, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200248 assert_int_equal(2, set.count);
249 assert_string_not_equal("string2", set.objs[0]);
250 assert_string_not_equal("string2", set.objs[1]);
Radek Krejci820d2262018-09-20 12:15:31 +0200251 /* ... last (with destructor) .. */
252 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str3, free));
Radek Krejci519b0432018-09-18 17:04:57 +0200253 assert_int_equal(1, set.count);
254 assert_string_not_equal("string3", set.objs[0]);
255 /* ... first .. */
Radek Krejci820d2262018-09-20 12:15:31 +0200256 assert_int_equal(LY_SUCCESS, ly_set_rm(&set, str1, NULL));
Radek Krejci519b0432018-09-18 17:04:57 +0200257 assert_int_equal(0, set.count);
258
259 /* cleanup */
260 ly_set_erase(&set, NULL);
261}
262
Radek Krejcib4ac5a92020-11-23 17:54:33 +0100263int
264main(void)
Radek Krejcie84f12f2018-09-18 14:11:50 +0200265{
266 const struct CMUnitTest tests[] = {
Radek Iša56ca9e42020-09-08 18:42:00 +0200267 UTEST(test_basics),
268 UTEST(test_duplication),
269 UTEST(test_add),
270 UTEST(test_merge),
271 UTEST(test_rm),
272 UTEST(test_inval),
Radek Krejcie84f12f2018-09-18 14:11:50 +0200273 };
274
275 return cmocka_run_group_tests(tests, NULL, NULL);
276}