1 /*
2 * lws-api-test-lws_map
3 *
4 * Written in 2010-2021 by Andy Green <andy@warmcat.com>
5 *
6 * This file is made available under the Creative Commons CC0 1.0
7 * Universal Public Domain Dedication.
8 *
9 * unit tests for lws_map
10 */
11
12 #include <libwebsockets.h>
13
14 typedef struct lws_map_item lws_map_item_t;
15
16 /* custom key and comparator for test 3 */
17
18 typedef struct mykey {
19 int key;
20 } mykey_t;
21
22 static int
compare_mykey_t(const lws_map_key_t key1, size_t kl1, const lws_map_value_t key2, size_t kl2)23 compare_mykey_t(const lws_map_key_t key1, size_t kl1,
24 const lws_map_value_t key2, size_t kl2)
25 {
26 const mykey_t *m1 = (mykey_t *)key1, *m2 = (mykey_t *)key2;
27
28 return m1->key != m2->key;
29 }
30
main(int argc, const char **argv)31 int main(int argc, const char **argv)
32 {
33 int e = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE,
34 expected = 4, pass = 0;
35 mykey_t k1 = { .key = 123 }, k2 = { .key = 234 }, k3 = { .key = 999 };
36 struct lwsac *ac = NULL;
37 lws_map_item_t *item;
38 lws_map_info_t info;
39 lws_map_t *map;
40 const char *p;
41
42 if ((p = lws_cmdline_option(argc, argv, "-d")))
43 logs = atoi(p);
44
45 lws_set_log_level(logs, NULL);
46 lwsl_user("LWS API selftest: lws_map\n");
47
48 /* Test 1: string keys */
49
50 lwsl_user("%s: test1\n", __func__);
51 memset(&info, 0, sizeof(info));
52 map = lws_map_create(&info);
53 if (!map) {
54 e++;
55 goto end_t1;
56 }
57 if (!lws_map_item_create_ks(map, "abc", (lws_map_value_t)"def", 3)) {
58 e++;
59 goto end_t1;
60 }
61 if (!lws_map_item_create_ks(map, "123", (lws_map_value_t)"4567", 4)) {
62 e++;
63 goto end_t1;
64 }
65 item = lws_map_item_lookup_ks(map, "abc");
66 if (!item) {
67 e++;
68 goto end_t1;
69 }
70
71 if (lws_map_item_value_len(item) != 3 ||
72 memcmp(lws_map_item_value(item), "def", 3)) {
73 e++;
74 goto end_t1;
75 }
76
77 item = lws_map_item_lookup_ks(map, "123");
78 if (!item) {
79 e++;
80 goto end_t1;
81 }
82
83 if (lws_map_item_value_len(item) != 4 ||
84 memcmp(lws_map_item_value(item), "4567", 4)) {
85 e++;
86 goto end_t1;
87 }
88
89 item = lws_map_item_lookup_ks(map, "nope");
90 if (item) {
91 e++;
92 goto end_t1;
93 }
94
95 pass++;
96
97 end_t1:
98 lws_map_destroy(&map);
99
100 /* Test 2: Use lwsac item allocators */
101
102 lwsl_user("%s: test2\n", __func__);
103 memset(&info, 0, sizeof(info));
104 info._alloc = lws_map_alloc_lwsac;
105 info._free = lws_map_free_lwsac;
106 info.opaque = (void *)∾
107
108 map = lws_map_create(&info);
109 if (!map) {
110 e++;
111 goto end_t2;
112 }
113 if (!lws_map_item_create_ks(map, "abc", "def", 3)) {
114 e++;
115 goto end_t2;
116 }
117 if (!lws_map_item_create_ks(map, "123", "4567", 4)) {
118 e++;
119 goto end_t2;
120 }
121 item = lws_map_item_lookup_ks(map, "abc");
122 if (!item) {
123 e++;
124 goto end_t2;
125 }
126
127 if (lws_map_item_value_len(item) != 3 ||
128 memcmp(lws_map_item_value(item), "def", 3)) {
129 e++;
130 goto end_t2;
131 }
132
133 item = lws_map_item_lookup_ks(map, "123");
134 if (!item) {
135 e++;
136 goto end_t2;
137 }
138
139 if (lws_map_item_value_len(item) != 4 ||
140 memcmp(lws_map_item_value(item), "4567", 4)) {
141 e++;
142 goto end_t2;
143 }
144
145 item = lws_map_item_lookup_ks(map, "nope");
146 if (item) {
147 e++;
148 goto end_t2;
149 }
150
151 pass++;
152
153 end_t2:
154 lws_map_destroy(&map);
155 lwsac_free(&ac);
156
157 /* Test 3: custom key object and comparator */
158
159 lwsl_user("%s: test3\n", __func__);
160 memset(&info, 0, sizeof(info));
161 info._compare = compare_mykey_t;
162
163 map = lws_map_create(&info);
164 if (!map) {
165 e++;
166 goto end_t3;
167 }
168 if (!lws_map_item_create(map, (lws_map_key_t)&k1, sizeof(k1),
169 (lws_map_value_t)"def", 3)) {
170 lwsl_err("%s: t3; a\n", __func__);
171 e++;
172 goto end_t3;
173 }
174 if (!lws_map_item_create(map, (lws_map_key_t)&k2, sizeof(k2),
175 (lws_map_value_t)"4567", 4)) {
176 lwsl_err("%s: t3; b\n", __func__);
177 e++;
178 goto end_t3;
179 }
180 item = lws_map_item_lookup(map, (lws_map_key_t)&k1, sizeof(k1));
181 if (!item) {
182 lwsl_err("%s: t3; c\n", __func__);
183 e++;
184 goto end_t3;
185 }
186
187 if (lws_map_item_value_len(item) != 3 ||
188 memcmp(lws_map_item_value(item), "def", 3)) {
189 lwsl_err("%s: t3; d\n", __func__);
190 e++;
191 goto end_t3;
192 }
193
194 item = lws_map_item_lookup(map, (lws_map_key_t)&k2, sizeof(k2));
195 if (!item) {
196 lwsl_err("%s: t3; e\n", __func__);
197 e++;
198 goto end_t3;
199 }
200
201 if (lws_map_item_value_len(item) != 4 ||
202 memcmp(lws_map_item_value(item), "4567", 4)) {
203 lwsl_err("%s: t3; f\n", __func__);
204 e++;
205 goto end_t3;
206 }
207
208 item = lws_map_item_lookup(map, (lws_map_key_t)&k3, sizeof(k3));
209 if (item) {
210 lwsl_err("%s: t3; g\n", __func__);
211 e++;
212 goto end_t3;
213 }
214
215 pass++;
216
217 end_t3:
218 lws_map_destroy(&map);
219
220 /* Test 4: same key items */
221
222 lwsl_user("%s: test4\n", __func__);
223 memset(&info, 0, sizeof(info));
224 map = lws_map_create(&info);
225 if (!map) {
226 e++;
227 goto end_t4;
228 }
229 if (!lws_map_item_create_ks(map, "abc", (lws_map_value_t)"def", 3)) {
230 e++;
231 goto end_t4;
232 }
233 if (!lws_map_item_create_ks(map, "abc", (lws_map_value_t)"4567", 4)) {
234 e++;
235 goto end_t4;
236 }
237 item = lws_map_item_lookup_ks(map, "abc");
238 if (!item) {
239 e++;
240 goto end_t4;
241 }
242
243 if (lws_map_item_value_len(item) != 4 ||
244 memcmp(lws_map_item_value(item), "4567", 4)) {
245 e++;
246 goto end_t4;
247 }
248
249 pass++;
250
251 end_t4:
252 lws_map_destroy(&map);
253
254 if (e)
255 goto bail;
256
257 lwsl_user("Completed: PASS %d / %d\n", pass, expected);
258
259 return 0;
260
261 bail:
262 lwsl_user("Completed: FAIL, passed %d / %d (e %d)\n", pass,
263 expected, e);
264
265 return 1;
266 }
267