]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-hashmap-plain.c
test: generate tests for OrderedHashmap from Hashmap tests
[thirdparty/systemd.git] / src / test / test-hashmap-plain.c
CommitLineData
32a4456c
MS
1/***
2 This file is part of systemd
3
4 Copyright 2013 Daniel Buch
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
20#include "strv.h"
21#include "util.h"
22#include "hashmap.h"
23
24void test_hashmap_funcs(void);
25
26static void test_hashmap_replace(void) {
27 Hashmap *m;
28 char *val1, *val2, *val3, *val4, *val5, *r;
29
30 m = hashmap_new(&string_hash_ops);
31
32 val1 = strdup("val1");
33 assert_se(val1);
34 val2 = strdup("val2");
35 assert_se(val2);
36 val3 = strdup("val3");
37 assert_se(val3);
38 val4 = strdup("val4");
39 assert_se(val4);
40 val5 = strdup("val5");
41 assert_se(val5);
42
43 hashmap_put(m, "key 1", val1);
44 hashmap_put(m, "key 2", val2);
45 hashmap_put(m, "key 3", val3);
46 hashmap_put(m, "key 4", val4);
47
48 hashmap_replace(m, "key 3", val1);
49 r = hashmap_get(m, "key 3");
50 assert_se(streq(r, "val1"));
51
52 hashmap_replace(m, "key 5", val5);
53 r = hashmap_get(m, "key 5");
54 assert_se(streq(r, "val5"));
55
56 free(val1);
57 free(val2);
58 free(val3);
59 free(val4);
60 free(val5);
61 hashmap_free(m);
62}
63
64static void test_hashmap_copy(void) {
65 Hashmap *m, *copy;
66 char *val1, *val2, *val3, *val4, *r;
67
68 val1 = strdup("val1");
69 assert_se(val1);
70 val2 = strdup("val2");
71 assert_se(val2);
72 val3 = strdup("val3");
73 assert_se(val3);
74 val4 = strdup("val4");
75 assert_se(val4);
76
77 m = hashmap_new(&string_hash_ops);
78
79 hashmap_put(m, "key 1", val1);
80 hashmap_put(m, "key 2", val2);
81 hashmap_put(m, "key 3", val3);
82 hashmap_put(m, "key 4", val4);
83
84 copy = hashmap_copy(m);
85
86 r = hashmap_get(copy, "key 1");
87 assert_se(streq(r, "val1"));
88 r = hashmap_get(copy, "key 2");
89 assert_se(streq(r, "val2"));
90 r = hashmap_get(copy, "key 3");
91 assert_se(streq(r, "val3"));
92 r = hashmap_get(copy, "key 4");
93 assert_se(streq(r, "val4"));
94
95 hashmap_free_free(copy);
96 hashmap_free(m);
97}
98
99static void test_hashmap_get_strv(void) {
100 Hashmap *m;
101 char **strv;
102 char *val1, *val2, *val3, *val4;
103
104 val1 = strdup("val1");
105 assert_se(val1);
106 val2 = strdup("val2");
107 assert_se(val2);
108 val3 = strdup("val3");
109 assert_se(val3);
110 val4 = strdup("val4");
111 assert_se(val4);
112
113 m = hashmap_new(&string_hash_ops);
114
115 hashmap_put(m, "key 1", val1);
116 hashmap_put(m, "key 2", val2);
117 hashmap_put(m, "key 3", val3);
118 hashmap_put(m, "key 4", val4);
119
120 strv = hashmap_get_strv(m);
121
122#ifndef ORDERED
123 strv = strv_sort(strv);
124#endif
125
126 assert_se(streq(strv[0], "val1"));
127 assert_se(streq(strv[1], "val2"));
128 assert_se(streq(strv[2], "val3"));
129 assert_se(streq(strv[3], "val4"));
130
131 strv_free(strv);
132
133 hashmap_free(m);
134}
135
136static void test_hashmap_move_one(void) {
137 Hashmap *m, *n;
138 char *val1, *val2, *val3, *val4, *r;
139
140 val1 = strdup("val1");
141 assert_se(val1);
142 val2 = strdup("val2");
143 assert_se(val2);
144 val3 = strdup("val3");
145 assert_se(val3);
146 val4 = strdup("val4");
147 assert_se(val4);
148
149 m = hashmap_new(&string_hash_ops);
150 n = hashmap_new(&string_hash_ops);
151
152 hashmap_put(m, "key 1", val1);
153 hashmap_put(m, "key 2", val2);
154 hashmap_put(m, "key 3", val3);
155 hashmap_put(m, "key 4", val4);
156
157 hashmap_move_one(n, m, "key 3");
158 hashmap_move_one(n, m, "key 4");
159
160 r = hashmap_get(n, "key 3");
161 assert_se(r && streq(r, "val3"));
162 r = hashmap_get(n, "key 4");
163 assert_se(r && streq(r, "val4"));
164 r = hashmap_get(m, "key 3");
165 assert_se(!r);
166
167
168 hashmap_free_free(m);
169 hashmap_free_free(n);
170}
171
172static void test_hashmap_update(void) {
173 Hashmap *m;
174 char *val1, *val2, *r;
175
176 m = hashmap_new(&string_hash_ops);
177 val1 = strdup("old_value");
178 assert_se(val1);
179 val2 = strdup("new_value");
180 assert_se(val2);
181
182 hashmap_put(m, "key 1", val1);
183 r = hashmap_get(m, "key 1");
184 assert_se(streq(r, "old_value"));
185
186 hashmap_update(m, "key 1", val2);
187 r = hashmap_get(m, "key 1");
188 assert_se(streq(r, "new_value"));
189
190 free(val1);
191 free(val2);
192 hashmap_free(m);
193}
194
195static void test_hashmap_put(void) {
196 Hashmap *m;
197 int valid_hashmap_put;
198
199 m = hashmap_new(&string_hash_ops);
200
201 valid_hashmap_put = hashmap_put(m, "key 1", (void*) (const char *) "val 1");
202 assert_se(valid_hashmap_put == 1);
203
204 assert_se(m);
205 hashmap_free(m);
206}
207
208static void test_hashmap_remove_and_put(void) {
209 _cleanup_hashmap_free_ Hashmap *m = NULL;
210 int valid;
211 char *r;
212
213 m = hashmap_new(&string_hash_ops);
214 assert_se(m);
215
216 valid = hashmap_remove_and_put(m, "unvalid key", "new key", NULL);
217 assert_se(valid < 0);
218
219 valid = hashmap_put(m, "key 1", (void*) (const char *) "val 1");
220 assert_se(valid == 1);
221 valid = hashmap_remove_and_put(m, "key 1", "key 2", (void*) (const char *) "val 2");
222 assert_se(valid == 0);
223
224 r = hashmap_get(m, "key 2");
225 assert_se(streq(r, "val 2"));
226 assert_se(!hashmap_get(m, "key 1"));
227
228 valid = hashmap_put(m, "key 3", (void*) (const char *) "val 3");
229 assert_se(valid == 1);
230 valid = hashmap_remove_and_put(m, "key 3", "key 2", (void*) (const char *) "val 2");
231 assert_se(valid < 0);
232}
233
234static void test_hashmap_ensure_allocated(void) {
235 Hashmap *m;
236 int valid_hashmap;
237
238 m = hashmap_new(&string_hash_ops);
239
240 valid_hashmap = hashmap_ensure_allocated(&m, &string_hash_ops);
241 assert_se(valid_hashmap == 0);
242
243 assert_se(m);
244 hashmap_free(m);
245}
246
247static void test_hashmap_foreach_key(void) {
248 Hashmap *m;
249 Iterator i;
250 bool key_found[] = { false, false, false, false };
251 const char *s;
252 const char *key;
253 static const char key_table[] =
254 "key 1\0"
255 "key 2\0"
256 "key 3\0"
257 "key 4\0";
258
259 m = hashmap_new(&string_hash_ops);
260
261 NULSTR_FOREACH(key, key_table)
262 hashmap_put(m, key, (void*) (const char*) "my dummy val");
263
264 HASHMAP_FOREACH_KEY(s, key, m, i) {
265 if (!key_found[0] && streq(key, "key 1"))
266 key_found[0] = true;
267 else if (!key_found[1] && streq(key, "key 2"))
268 key_found[1] = true;
269 else if (!key_found[2] && streq(key, "key 3"))
270 key_found[2] = true;
271 else if (!key_found[3] && streq(key, "fail"))
272 key_found[3] = true;
273 }
274
275 assert_se(m);
276 assert_se(key_found[0] && key_found[1] && key_found[2] && !key_found[3]);
277
278 hashmap_free(m);
279}
280
281static void test_hashmap_foreach(void) {
282 Hashmap *m;
283 Iterator i;
284 bool value_found[] = { false, false, false, false };
285 char *val1, *val2, *val3, *val4, *s;
286
287 val1 = strdup("my val1");
288 assert_se(val1);
289 val2 = strdup("my val2");
290 assert_se(val2);
291 val3 = strdup("my val3");
292 assert_se(val3);
293 val4 = strdup("my val4");
294 assert_se(val4);
295
296 m = hashmap_new(&string_hash_ops);
297
298 hashmap_put(m, "Key 1", val1);
299 hashmap_put(m, "Key 2", val2);
300 hashmap_put(m, "Key 3", val3);
301 hashmap_put(m, "Key 4", val4);
302
303 HASHMAP_FOREACH(s, m, i) {
304 if (!value_found[0] && streq(s, val1))
305 value_found[0] = true;
306 else if (!value_found[1] && streq(s, val2))
307 value_found[1] = true;
308 else if (!value_found[2] && streq(s, val3))
309 value_found[2] = true;
310 else if (!value_found[3] && streq(s, val4))
311 value_found[3] = true;
312 }
313
314 assert_se(m);
315 assert_se(value_found[0] && value_found[1] && value_found[2] && value_found[3]);
316
317 hashmap_free_free(m);
318}
319
320static void test_hashmap_merge(void) {
321 Hashmap *m;
322 Hashmap *n;
323 char *val1, *val2, *val3, *val4, *r;
324
325 val1 = strdup("my val1");
326 assert_se(val1);
327 val2 = strdup("my val2");
328 assert_se(val2);
329 val3 = strdup("my val3");
330 assert_se(val3);
331 val4 = strdup("my val4");
332 assert_se(val4);
333
334 n = hashmap_new(&string_hash_ops);
335 m = hashmap_new(&string_hash_ops);
336
337 hashmap_put(m, "Key 1", val1);
338 hashmap_put(m, "Key 2", val2);
339 hashmap_put(n, "Key 3", val3);
340 hashmap_put(n, "Key 4", val4);
341
342 assert_se(hashmap_merge(m, n) == 0);
343 r = hashmap_get(m, "Key 3");
344 assert_se(r && streq(r, "my val3"));
345 r = hashmap_get(m, "Key 4");
346 assert_se(r && streq(r, "my val4"));
347
348 assert_se(n);
349 assert_se(m);
350 hashmap_free(n);
351 hashmap_free_free(m);
352}
353
354static void test_hashmap_contains(void) {
355 Hashmap *m;
356 char *val1;
357
358 val1 = strdup("my val");
359 assert_se(val1);
360
361 m = hashmap_new(&string_hash_ops);
362
363 assert_se(!hashmap_contains(m, "Key 1"));
364 hashmap_put(m, "Key 1", val1);
365 assert_se(hashmap_contains(m, "Key 1"));
366
367 assert_se(m);
368 hashmap_free_free(m);
369}
370
371static void test_hashmap_isempty(void) {
372 Hashmap *m;
373 char *val1;
374
375 val1 = strdup("my val");
376 assert_se(val1);
377
378 m = hashmap_new(&string_hash_ops);
379
380 assert_se(hashmap_isempty(m));
381 hashmap_put(m, "Key 1", val1);
382 assert_se(!hashmap_isempty(m));
383
384 assert_se(m);
385 hashmap_free_free(m);
386}
387
388static void test_hashmap_size(void) {
389 Hashmap *m;
390 char *val1, *val2, *val3, *val4;
391
392 val1 = strdup("my val");
393 assert_se(val1);
394 val2 = strdup("my val");
395 assert_se(val2);
396 val3 = strdup("my val");
397 assert_se(val3);
398 val4 = strdup("my val");
399 assert_se(val4);
400
401 m = hashmap_new(&string_hash_ops);
402
403 hashmap_put(m, "Key 1", val1);
404 hashmap_put(m, "Key 2", val2);
405 hashmap_put(m, "Key 3", val3);
406 hashmap_put(m, "Key 4", val4);
407
408 assert_se(m);
409 assert_se(hashmap_size(m) == 4);
410 hashmap_free_free(m);
411}
412
413static void test_hashmap_get(void) {
414 Hashmap *m;
415 char *r;
416 char *val;
417
418 val = strdup("my val");
419 assert_se(val);
420
421 m = hashmap_new(&string_hash_ops);
422
423 hashmap_put(m, "Key 1", val);
424
425 r = hashmap_get(m, "Key 1");
426 assert_se(streq(r, val));
427
428 assert_se(m);
429 hashmap_free_free(m);
430}
431
432static void test_hashmap_many(void) {
433 Hashmap *h;
434 unsigned i;
435
436#define N_ENTRIES 100000
437
438 assert_se(h = hashmap_new(NULL));
439
440 for (i = 1; i < N_ENTRIES*3; i+=3) {
441 assert_se(hashmap_put(h, UINT_TO_PTR(i), UINT_TO_PTR(i)) >= 0);
442 assert_se(PTR_TO_UINT(hashmap_get(h, UINT_TO_PTR(i))) == i);
443 }
444
445 for (i = 1; i < N_ENTRIES*3; i++)
446 assert_se(hashmap_contains(h, UINT_TO_PTR(i)) == (i % 3 == 1));
447
448 log_info("%u <= %u * 0.75 = %g", hashmap_size(h), hashmap_buckets(h), hashmap_buckets(h) * 0.75);
449
450 assert_se(hashmap_size(h) <= hashmap_buckets(h) * 0.75);
451 assert_se(hashmap_size(h) == N_ENTRIES);
452
453 hashmap_free(h);
454}
455
456static void test_hashmap_first_key(void) {
457 _cleanup_hashmap_free_ Hashmap *m = NULL;
458
459 m = hashmap_new(&string_hash_ops);
460 assert_se(m);
461
462 assert_se(!hashmap_first_key(m));
463 assert_se(hashmap_put(m, "key 1", NULL) == 1);
464 assert_se(streq(hashmap_first_key(m), "key 1"));
465 assert_se(hashmap_put(m, "key 2", NULL) == 1);
466#ifdef ORDERED
467 assert_se(streq(hashmap_first_key(m), "key 1"));
468 assert_se(hashmap_remove(m, "key 1") == NULL);
469 assert_se(streq(hashmap_first_key(m), "key 2"));
470#endif
471}
472
473static void test_hashmap_steal_first_key(void) {
474 _cleanup_hashmap_free_ Hashmap *m = NULL;
475
476 m = hashmap_new(&string_hash_ops);
477 assert_se(m);
478
479 assert_se(!hashmap_steal_first_key(m));
480 assert_se(hashmap_put(m, "key 1", NULL) == 1);
481 assert_se(streq(hashmap_steal_first_key(m), "key 1"));
482
483 assert_se(hashmap_isempty(m));
484}
485
486static void test_hashmap_steal_first(void) {
487 _cleanup_hashmap_free_ Hashmap *m = NULL;
488 int seen[3] = {};
489 char *val;
490
491 m = hashmap_new(&string_hash_ops);
492 assert_se(m);
493
494 assert_se(hashmap_put(m, "key 1", (void*) "1") == 1);
495 assert_se(hashmap_put(m, "key 2", (void*) "22") == 1);
496 assert_se(hashmap_put(m, "key 3", (void*) "333") == 1);
497
498 while ((val = hashmap_steal_first(m)))
499 seen[strlen(val) - 1]++;
500
501 assert_se(seen[0] == 1 && seen[1] == 1 && seen[2] == 1);
502
503 assert_se(hashmap_isempty(m));
504}
505
506static void test_hashmap_clear_free_free(void) {
507 _cleanup_hashmap_free_ Hashmap *m = NULL;
508
509 m = hashmap_new(&string_hash_ops);
510 assert_se(m);
511
512 assert_se(hashmap_put(m, strdup("key 1"), NULL) == 1);
513 assert_se(hashmap_put(m, strdup("key 2"), NULL) == 1);
514 assert_se(hashmap_put(m, strdup("key 3"), NULL) == 1);
515
516 hashmap_clear_free_free(m);
517 assert_se(hashmap_isempty(m));
518}
519
520void test_hashmap_funcs(void) {
521 test_hashmap_copy();
522 test_hashmap_get_strv();
523 test_hashmap_move_one();
524 test_hashmap_replace();
525 test_hashmap_update();
526 test_hashmap_put();
527 test_hashmap_remove_and_put();
528 test_hashmap_ensure_allocated();
529 test_hashmap_foreach();
530 test_hashmap_foreach_key();
531 test_hashmap_contains();
532 test_hashmap_merge();
533 test_hashmap_isempty();
534 test_hashmap_get();
535 test_hashmap_size();
536 test_hashmap_many();
537 test_hashmap_first_key();
538 test_hashmap_steal_first_key();
539 test_hashmap_steal_first();
540 test_hashmap_clear_free_free();
541}