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