]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-hashmap-plain.c
mempool: add a zeroing alloc function
[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
9ba81d5a
MS
157 assert_se(hashmap_move_one(n, NULL, "key 3") == -ENOENT);
158 assert_se(hashmap_move_one(n, m, "key 5") == -ENOENT);
159 assert_se(hashmap_move_one(n, m, "key 3") == 0);
160 assert_se(hashmap_move_one(n, m, "key 4") == 0);
32a4456c
MS
161
162 r = hashmap_get(n, "key 3");
163 assert_se(r && streq(r, "val3"));
164 r = hashmap_get(n, "key 4");
165 assert_se(r && streq(r, "val4"));
166 r = hashmap_get(m, "key 3");
167 assert_se(!r);
168
9ba81d5a
MS
169 assert_se(hashmap_move_one(n, m, "key 3") == -EEXIST);
170
171 hashmap_free_free(m);
172 hashmap_free_free(n);
173}
174
175static void test_hashmap_move(void) {
176 Hashmap *m, *n;
177 char *val1, *val2, *val3, *val4, *r;
178
179 val1 = strdup("val1");
180 assert_se(val1);
181 val2 = strdup("val2");
182 assert_se(val2);
183 val3 = strdup("val3");
184 assert_se(val3);
185 val4 = strdup("val4");
186 assert_se(val4);
187
188 m = hashmap_new(&string_hash_ops);
189 n = hashmap_new(&string_hash_ops);
190
191 hashmap_put(n, "key 1", strdup(val1));
192 hashmap_put(m, "key 1", val1);
193 hashmap_put(m, "key 2", val2);
194 hashmap_put(m, "key 3", val3);
195 hashmap_put(m, "key 4", val4);
196
7ad63f57
MS
197 assert(hashmap_move(n, NULL) == 0);
198 assert(hashmap_move(n, m) == 0);
9ba81d5a
MS
199
200 assert_se(hashmap_size(m) == 1);
201 r = hashmap_get(m, "key 1");
202 assert_se(r && streq(r, "val1"));
203
204 r = hashmap_get(n, "key 1");
205 assert_se(r && streq(r, "val1"));
206 r = hashmap_get(n, "key 2");
207 assert_se(r && streq(r, "val2"));
208 r = hashmap_get(n, "key 3");
209 assert_se(r && streq(r, "val3"));
210 r = hashmap_get(n, "key 4");
211 assert_se(r && streq(r, "val4"));
32a4456c
MS
212
213 hashmap_free_free(m);
214 hashmap_free_free(n);
215}
216
217static void test_hashmap_update(void) {
218 Hashmap *m;
219 char *val1, *val2, *r;
220
221 m = hashmap_new(&string_hash_ops);
222 val1 = strdup("old_value");
223 assert_se(val1);
224 val2 = strdup("new_value");
225 assert_se(val2);
226
227 hashmap_put(m, "key 1", val1);
228 r = hashmap_get(m, "key 1");
229 assert_se(streq(r, "old_value"));
230
9ba81d5a
MS
231 assert_se(hashmap_update(m, "key 2", val2) == -ENOENT);
232 r = hashmap_get(m, "key 1");
233 assert_se(streq(r, "old_value"));
234
235 assert_se(hashmap_update(m, "key 1", val2) == 0);
32a4456c
MS
236 r = hashmap_get(m, "key 1");
237 assert_se(streq(r, "new_value"));
238
239 free(val1);
240 free(val2);
241 hashmap_free(m);
242}
243
244static void test_hashmap_put(void) {
9ba81d5a 245 Hashmap *m = NULL;
32a4456c 246 int valid_hashmap_put;
9ba81d5a 247 void *val1 = (void*) "val 1";
32a4456c 248
9ba81d5a
MS
249 hashmap_ensure_allocated(&m, &string_hash_ops);
250 assert_se(m);
32a4456c 251
9ba81d5a 252 valid_hashmap_put = hashmap_put(m, "key 1", val1);
32a4456c 253 assert_se(valid_hashmap_put == 1);
9ba81d5a
MS
254 assert_se(hashmap_put(m, "key 1", val1) == 0);
255 assert_se(hashmap_put(m, "key 1", (void *)"val 2") == -EEXIST);
32a4456c 256
32a4456c
MS
257 hashmap_free(m);
258}
259
9ba81d5a
MS
260static void test_hashmap_remove(void) {
261 _cleanup_hashmap_free_ Hashmap *m = NULL;
262 char *r;
263
264 r = hashmap_remove(NULL, "key 1");
265 assert_se(r == NULL);
266
267 m = hashmap_new(&string_hash_ops);
268 assert_se(m);
269
270 r = hashmap_remove(m, "no such key");
271 assert_se(r == NULL);
272
273 hashmap_put(m, "key 1", (void*) "val 1");
274 hashmap_put(m, "key 2", (void*) "val 2");
275
276 r = hashmap_remove(m, "key 1");
277 assert_se(streq(r, "val 1"));
278
279 r = hashmap_get(m, "key 2");
280 assert_se(streq(r, "val 2"));
281 assert_se(!hashmap_get(m, "key 1"));
282}
283
284static void test_hashmap_remove2(void) {
285 _cleanup_hashmap_free_free_free_ Hashmap *m = NULL;
286 char key1[] = "key 1";
287 char key2[] = "key 2";
288 char val1[] = "val 1";
289 char val2[] = "val 2";
290 void *r, *r2;
291
292 r = hashmap_remove2(NULL, "key 1", &r2);
293 assert_se(r == NULL);
294
295 m = hashmap_new(&string_hash_ops);
296 assert_se(m);
297
298 r = hashmap_remove2(m, "no such key", &r2);
299 assert_se(r == NULL);
300
301 hashmap_put(m, strdup(key1), strdup(val1));
302 hashmap_put(m, strdup(key2), strdup(val2));
303
304 r = hashmap_remove2(m, key1, &r2);
305 assert_se(streq(r, val1));
306 assert_se(streq(r2, key1));
307 free(r);
308 free(r2);
309
310 r = hashmap_get(m, key2);
311 assert_se(streq(r, val2));
312 assert_se(!hashmap_get(m, key1));
313}
314
315static void test_hashmap_remove_value(void) {
316 _cleanup_hashmap_free_ Hashmap *m = NULL;
317 char *r;
318
319 r = hashmap_remove_value(NULL, "key 1", (void*) "val 1");
320 assert_se(r == NULL);
321
322 m = hashmap_new(&string_hash_ops);
323 assert_se(m);
324
325 r = hashmap_remove_value(m, "key 1", (void*) "val 1");
326 assert_se(r == NULL);
327
328 hashmap_put(m, "key 1", (void*) "val 1");
329 hashmap_put(m, "key 2", (void*) "val 2");
330
331 r = hashmap_remove_value(m, "key 1", (void*) "val 1");
332 assert_se(streq(r, "val 1"));
333
334 r = hashmap_get(m, "key 2");
335 assert_se(streq(r, "val 2"));
336 assert_se(!hashmap_get(m, "key 1"));
337
338 r = hashmap_remove_value(m, "key 2", (void*) "val 1");
339 assert_se(r == NULL);
340
341 r = hashmap_get(m, "key 2");
342 assert_se(streq(r, "val 2"));
343 assert_se(!hashmap_get(m, "key 1"));
344}
345
32a4456c
MS
346static void test_hashmap_remove_and_put(void) {
347 _cleanup_hashmap_free_ Hashmap *m = NULL;
348 int valid;
349 char *r;
350
351 m = hashmap_new(&string_hash_ops);
352 assert_se(m);
353
9ba81d5a
MS
354 valid = hashmap_remove_and_put(m, "invalid key", "new key", NULL);
355 assert_se(valid == -ENOENT);
32a4456c
MS
356
357 valid = hashmap_put(m, "key 1", (void*) (const char *) "val 1");
358 assert_se(valid == 1);
9ba81d5a
MS
359
360 valid = hashmap_remove_and_put(NULL, "key 1", "key 2", (void*) (const char *) "val 2");
361 assert_se(valid == -ENOENT);
362
32a4456c
MS
363 valid = hashmap_remove_and_put(m, "key 1", "key 2", (void*) (const char *) "val 2");
364 assert_se(valid == 0);
365
366 r = hashmap_get(m, "key 2");
367 assert_se(streq(r, "val 2"));
368 assert_se(!hashmap_get(m, "key 1"));
369
370 valid = hashmap_put(m, "key 3", (void*) (const char *) "val 3");
371 assert_se(valid == 1);
372 valid = hashmap_remove_and_put(m, "key 3", "key 2", (void*) (const char *) "val 2");
9ba81d5a
MS
373 assert_se(valid == -EEXIST);
374}
375
376static void test_hashmap_remove_and_replace(void) {
377 _cleanup_hashmap_free_ Hashmap *m = NULL;
378 int valid;
379 void *key1 = UINT_TO_PTR(1);
380 void *key2 = UINT_TO_PTR(2);
381 void *key3 = UINT_TO_PTR(3);
382 void *r;
383
384 m = hashmap_new(&trivial_hash_ops);
385 assert_se(m);
386
387 valid = hashmap_remove_and_replace(m, key1, key2, NULL);
388 assert_se(valid == -ENOENT);
389
390 valid = hashmap_put(m, key1, key1);
391 assert_se(valid == 1);
392
393 valid = hashmap_remove_and_replace(NULL, key1, key2, key2);
394 assert_se(valid == -ENOENT);
395
396 valid = hashmap_remove_and_replace(m, key1, key2, key2);
397 assert_se(valid == 0);
398
399 r = hashmap_get(m, key2);
400 assert_se(r == key2);
401 assert_se(!hashmap_get(m, key1));
402
403 valid = hashmap_put(m, key3, key3);
404 assert_se(valid == 1);
405 valid = hashmap_remove_and_replace(m, key3, key2, key2);
406 assert_se(valid == 0);
407 r = hashmap_get(m, key2);
408 assert_se(r == key2);
409 assert_se(!hashmap_get(m, key3));
32a4456c
MS
410}
411
412static void test_hashmap_ensure_allocated(void) {
413 Hashmap *m;
414 int valid_hashmap;
415
416 m = hashmap_new(&string_hash_ops);
417
418 valid_hashmap = hashmap_ensure_allocated(&m, &string_hash_ops);
419 assert_se(valid_hashmap == 0);
420
421 assert_se(m);
422 hashmap_free(m);
423}
424
425static void test_hashmap_foreach_key(void) {
426 Hashmap *m;
427 Iterator i;
428 bool key_found[] = { false, false, false, false };
429 const char *s;
430 const char *key;
431 static const char key_table[] =
432 "key 1\0"
433 "key 2\0"
434 "key 3\0"
435 "key 4\0";
436
437 m = hashmap_new(&string_hash_ops);
438
439 NULSTR_FOREACH(key, key_table)
440 hashmap_put(m, key, (void*) (const char*) "my dummy val");
441
442 HASHMAP_FOREACH_KEY(s, key, m, i) {
443 if (!key_found[0] && streq(key, "key 1"))
444 key_found[0] = true;
445 else if (!key_found[1] && streq(key, "key 2"))
446 key_found[1] = true;
447 else if (!key_found[2] && streq(key, "key 3"))
448 key_found[2] = true;
449 else if (!key_found[3] && streq(key, "fail"))
450 key_found[3] = true;
451 }
452
453 assert_se(m);
454 assert_se(key_found[0] && key_found[1] && key_found[2] && !key_found[3]);
455
456 hashmap_free(m);
457}
458
459static void test_hashmap_foreach(void) {
460 Hashmap *m;
461 Iterator i;
462 bool value_found[] = { false, false, false, false };
463 char *val1, *val2, *val3, *val4, *s;
9ba81d5a 464 unsigned count;
32a4456c
MS
465
466 val1 = strdup("my val1");
467 assert_se(val1);
468 val2 = strdup("my val2");
469 assert_se(val2);
470 val3 = strdup("my val3");
471 assert_se(val3);
472 val4 = strdup("my val4");
473 assert_se(val4);
474
9ba81d5a
MS
475 m = NULL;
476
477 count = 0;
478 HASHMAP_FOREACH(s, m, i)
479 count++;
480 assert_se(count == 0);
481
32a4456c
MS
482 m = hashmap_new(&string_hash_ops);
483
9ba81d5a
MS
484 count = 0;
485 HASHMAP_FOREACH(s, m, i)
486 count++;
487 assert_se(count == 0);
488
32a4456c
MS
489 hashmap_put(m, "Key 1", val1);
490 hashmap_put(m, "Key 2", val2);
491 hashmap_put(m, "Key 3", val3);
492 hashmap_put(m, "Key 4", val4);
493
494 HASHMAP_FOREACH(s, m, i) {
495 if (!value_found[0] && streq(s, val1))
496 value_found[0] = true;
497 else if (!value_found[1] && streq(s, val2))
498 value_found[1] = true;
499 else if (!value_found[2] && streq(s, val3))
500 value_found[2] = true;
501 else if (!value_found[3] && streq(s, val4))
502 value_found[3] = true;
503 }
504
505 assert_se(m);
506 assert_se(value_found[0] && value_found[1] && value_found[2] && value_found[3]);
507
508 hashmap_free_free(m);
509}
510
511static void test_hashmap_merge(void) {
512 Hashmap *m;
513 Hashmap *n;
514 char *val1, *val2, *val3, *val4, *r;
515
516 val1 = strdup("my val1");
517 assert_se(val1);
518 val2 = strdup("my val2");
519 assert_se(val2);
520 val3 = strdup("my val3");
521 assert_se(val3);
522 val4 = strdup("my val4");
523 assert_se(val4);
524
525 n = hashmap_new(&string_hash_ops);
526 m = hashmap_new(&string_hash_ops);
527
528 hashmap_put(m, "Key 1", val1);
529 hashmap_put(m, "Key 2", val2);
530 hashmap_put(n, "Key 3", val3);
531 hashmap_put(n, "Key 4", val4);
532
533 assert_se(hashmap_merge(m, n) == 0);
534 r = hashmap_get(m, "Key 3");
535 assert_se(r && streq(r, "my val3"));
536 r = hashmap_get(m, "Key 4");
537 assert_se(r && streq(r, "my val4"));
538
539 assert_se(n);
540 assert_se(m);
541 hashmap_free(n);
542 hashmap_free_free(m);
543}
544
545static void test_hashmap_contains(void) {
546 Hashmap *m;
547 char *val1;
548
549 val1 = strdup("my val");
550 assert_se(val1);
551
552 m = hashmap_new(&string_hash_ops);
553
554 assert_se(!hashmap_contains(m, "Key 1"));
555 hashmap_put(m, "Key 1", val1);
556 assert_se(hashmap_contains(m, "Key 1"));
9ba81d5a
MS
557 assert_se(!hashmap_contains(m, "Key 2"));
558
559 assert_se(!hashmap_contains(NULL, "Key 1"));
32a4456c
MS
560
561 assert_se(m);
562 hashmap_free_free(m);
563}
564
565static void test_hashmap_isempty(void) {
566 Hashmap *m;
567 char *val1;
568
569 val1 = strdup("my val");
570 assert_se(val1);
571
572 m = hashmap_new(&string_hash_ops);
573
574 assert_se(hashmap_isempty(m));
575 hashmap_put(m, "Key 1", val1);
576 assert_se(!hashmap_isempty(m));
577
578 assert_se(m);
579 hashmap_free_free(m);
580}
581
582static void test_hashmap_size(void) {
583 Hashmap *m;
584 char *val1, *val2, *val3, *val4;
585
586 val1 = strdup("my val");
587 assert_se(val1);
588 val2 = strdup("my val");
589 assert_se(val2);
590 val3 = strdup("my val");
591 assert_se(val3);
592 val4 = strdup("my val");
593 assert_se(val4);
594
9ba81d5a
MS
595 assert_se(hashmap_size(NULL) == 0);
596 assert_se(hashmap_buckets(NULL) == 0);
597
32a4456c
MS
598 m = hashmap_new(&string_hash_ops);
599
600 hashmap_put(m, "Key 1", val1);
601 hashmap_put(m, "Key 2", val2);
602 hashmap_put(m, "Key 3", val3);
603 hashmap_put(m, "Key 4", val4);
604
605 assert_se(m);
606 assert_se(hashmap_size(m) == 4);
9ba81d5a 607 assert_se(hashmap_buckets(m) >= 4);
32a4456c
MS
608 hashmap_free_free(m);
609}
610
611static void test_hashmap_get(void) {
612 Hashmap *m;
613 char *r;
614 char *val;
615
616 val = strdup("my val");
617 assert_se(val);
618
9ba81d5a
MS
619 r = hashmap_get(NULL, "Key 1");
620 assert_se(r == NULL);
621
32a4456c
MS
622 m = hashmap_new(&string_hash_ops);
623
624 hashmap_put(m, "Key 1", val);
625
626 r = hashmap_get(m, "Key 1");
627 assert_se(streq(r, val));
628
9ba81d5a
MS
629 r = hashmap_get(m, "no such key");
630 assert_se(r == NULL);
631
32a4456c
MS
632 assert_se(m);
633 hashmap_free_free(m);
634}
635
9ba81d5a
MS
636static void test_hashmap_get2(void) {
637 Hashmap *m;
638 char *r;
639 char *val;
640 char key_orig[] = "Key 1";
641 void *key_copy;
642
643 val = strdup("my val");
644 assert_se(val);
645
646 key_copy = strdup(key_orig);
647 assert_se(key_copy);
648
649 r = hashmap_get2(NULL, key_orig, &key_copy);
650 assert_se(r == NULL);
651
652 m = hashmap_new(&string_hash_ops);
653
654 hashmap_put(m, key_copy, val);
655 key_copy = NULL;
656
657 r = hashmap_get2(m, key_orig, &key_copy);
658 assert_se(streq(r, val));
659 assert_se(key_orig != key_copy);
660 assert_se(streq(key_orig, key_orig));
661
662 r = hashmap_get2(m, "no such key", NULL);
663 assert_se(r == NULL);
664
665 assert_se(m);
666 hashmap_free_free_free(m);
667}
668
669static unsigned long crippled_hashmap_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) {
670 return trivial_hash_func(p, hash_key) & 0xff;
671}
672
673static const struct hash_ops crippled_hashmap_ops = {
674 .hash = crippled_hashmap_func,
675 .compare = trivial_compare_func,
676};
677
32a4456c
MS
678static void test_hashmap_many(void) {
679 Hashmap *h;
9ba81d5a
MS
680 unsigned i, j;
681 void *v, *k;
682 static const struct {
683 const struct hash_ops *ops;
684 unsigned n_entries;
685 } tests[] = {
686 { .ops = NULL, .n_entries = 1 << 20 },
687 { .ops = &crippled_hashmap_ops, .n_entries = 1 << 11 },
688 };
32a4456c 689
32a4456c 690
9ba81d5a
MS
691 for (j = 0; j < ELEMENTSOF(tests); j++) {
692 assert_se(h = hashmap_new(tests[j].ops));
32a4456c 693
9ba81d5a
MS
694 for (i = 1; i < tests[j].n_entries*3; i+=3) {
695 assert_se(hashmap_put(h, UINT_TO_PTR(i), UINT_TO_PTR(i)) >= 0);
696 assert_se(PTR_TO_UINT(hashmap_get(h, UINT_TO_PTR(i))) == i);
697 }
698
699 for (i = 1; i < tests[j].n_entries*3; i++)
700 assert_se(hashmap_contains(h, UINT_TO_PTR(i)) == (i % 3 == 1));
32a4456c 701
9ba81d5a 702 log_info("%u <= %u * 0.75 = %g", hashmap_size(h), hashmap_buckets(h), hashmap_buckets(h) * 0.75);
32a4456c 703
9ba81d5a
MS
704 assert_se(hashmap_size(h) <= hashmap_buckets(h) * 0.75);
705 assert_se(hashmap_size(h) == tests[j].n_entries);
32a4456c 706
9ba81d5a
MS
707 while (!hashmap_isempty(h)) {
708 k = hashmap_first_key(h);
709 v = hashmap_remove(h, k);
710 assert_se(v == k);
711 }
32a4456c 712
9ba81d5a
MS
713 hashmap_free(h);
714 }
715}
716
717static void test_hashmap_first(void) {
718 _cleanup_hashmap_free_ Hashmap *m = NULL;
719
720 m = hashmap_new(&string_hash_ops);
721 assert_se(m);
722
723 assert_se(!hashmap_first(m));
724 assert_se(hashmap_put(m, "key 1", (void*) "val 1") == 1);
725 assert_se(streq(hashmap_first(m), "val 1"));
726 assert_se(hashmap_put(m, "key 2", (void*) "val 2") == 1);
727#ifdef ORDERED
728 assert_se(streq(hashmap_first(m), "val 1"));
729 assert_se(hashmap_remove(m, "key 1"));
730 assert_se(streq(hashmap_first(m), "val 2"));
731#endif
32a4456c
MS
732}
733
734static void test_hashmap_first_key(void) {
735 _cleanup_hashmap_free_ Hashmap *m = NULL;
736
737 m = hashmap_new(&string_hash_ops);
738 assert_se(m);
739
740 assert_se(!hashmap_first_key(m));
741 assert_se(hashmap_put(m, "key 1", NULL) == 1);
742 assert_se(streq(hashmap_first_key(m), "key 1"));
743 assert_se(hashmap_put(m, "key 2", NULL) == 1);
744#ifdef ORDERED
745 assert_se(streq(hashmap_first_key(m), "key 1"));
746 assert_se(hashmap_remove(m, "key 1") == NULL);
747 assert_se(streq(hashmap_first_key(m), "key 2"));
748#endif
749}
750
751static void test_hashmap_steal_first_key(void) {
752 _cleanup_hashmap_free_ Hashmap *m = NULL;
753
754 m = hashmap_new(&string_hash_ops);
755 assert_se(m);
756
757 assert_se(!hashmap_steal_first_key(m));
758 assert_se(hashmap_put(m, "key 1", NULL) == 1);
759 assert_se(streq(hashmap_steal_first_key(m), "key 1"));
760
761 assert_se(hashmap_isempty(m));
762}
763
764static void test_hashmap_steal_first(void) {
765 _cleanup_hashmap_free_ Hashmap *m = NULL;
766 int seen[3] = {};
767 char *val;
768
769 m = hashmap_new(&string_hash_ops);
770 assert_se(m);
771
772 assert_se(hashmap_put(m, "key 1", (void*) "1") == 1);
773 assert_se(hashmap_put(m, "key 2", (void*) "22") == 1);
774 assert_se(hashmap_put(m, "key 3", (void*) "333") == 1);
775
776 while ((val = hashmap_steal_first(m)))
777 seen[strlen(val) - 1]++;
778
779 assert_se(seen[0] == 1 && seen[1] == 1 && seen[2] == 1);
780
781 assert_se(hashmap_isempty(m));
782}
783
784static void test_hashmap_clear_free_free(void) {
785 _cleanup_hashmap_free_ Hashmap *m = NULL;
786
787 m = hashmap_new(&string_hash_ops);
788 assert_se(m);
789
790 assert_se(hashmap_put(m, strdup("key 1"), NULL) == 1);
791 assert_se(hashmap_put(m, strdup("key 2"), NULL) == 1);
792 assert_se(hashmap_put(m, strdup("key 3"), NULL) == 1);
793
794 hashmap_clear_free_free(m);
795 assert_se(hashmap_isempty(m));
796}
797
8f88aed7
MS
798static void test_hashmap_reserve(void) {
799 _cleanup_hashmap_free_ Hashmap *m = NULL;
800
801 m = hashmap_new(&string_hash_ops);
802
803 assert_se(hashmap_reserve(m, 1) == 0);
804 assert_se(hashmap_buckets(m) < 1000);
805 assert_se(hashmap_reserve(m, 1000) == 0);
806 assert_se(hashmap_buckets(m) >= 1000);
807 assert_se(hashmap_isempty(m));
808
809 assert_se(hashmap_put(m, "key 1", (void*) "val 1") == 1);
810
811 assert_se(hashmap_reserve(m, UINT_MAX) == -ENOMEM);
812 assert_se(hashmap_reserve(m, UINT_MAX - 1) == -ENOMEM);
813}
814
32a4456c
MS
815void test_hashmap_funcs(void) {
816 test_hashmap_copy();
817 test_hashmap_get_strv();
818 test_hashmap_move_one();
9ba81d5a 819 test_hashmap_move();
32a4456c
MS
820 test_hashmap_replace();
821 test_hashmap_update();
822 test_hashmap_put();
9ba81d5a
MS
823 test_hashmap_remove();
824 test_hashmap_remove2();
825 test_hashmap_remove_value();
32a4456c 826 test_hashmap_remove_and_put();
9ba81d5a 827 test_hashmap_remove_and_replace();
32a4456c
MS
828 test_hashmap_ensure_allocated();
829 test_hashmap_foreach();
830 test_hashmap_foreach_key();
831 test_hashmap_contains();
832 test_hashmap_merge();
833 test_hashmap_isempty();
834 test_hashmap_get();
9ba81d5a 835 test_hashmap_get2();
32a4456c
MS
836 test_hashmap_size();
837 test_hashmap_many();
9ba81d5a 838 test_hashmap_first();
32a4456c
MS
839 test_hashmap_first_key();
840 test_hashmap_steal_first_key();
841 test_hashmap_steal_first();
842 test_hashmap_clear_free_free();
8f88aed7 843 test_hashmap_reserve();
32a4456c 844}