]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
9341a4a1 | 2 | |
9341a4a1 | 3 | #include "hashmap.h" |
c462e63e | 4 | #include "tests.h" |
9341a4a1 | 5 | |
8872c3a3 ZJS |
6 | unsigned custom_counter = 0; |
7 | static void custom_destruct(void* p) { | |
8 | custom_counter--; | |
9 | free(p); | |
10 | } | |
11 | ||
12 | DEFINE_HASH_OPS_FULL(boring_hash_ops, char, string_hash_func, string_compare_func, free, char, free); | |
13 | DEFINE_HASH_OPS_FULL(custom_hash_ops, char, string_hash_func, string_compare_func, custom_destruct, char, custom_destruct); | |
14 | ||
c462e63e | 15 | TEST(ordered_hashmap_next) { |
8f8a5213 MS |
16 | _cleanup_ordered_hashmap_free_ OrderedHashmap *m = NULL; |
17 | int i; | |
18 | ||
19 | assert_se(m = ordered_hashmap_new(NULL)); | |
20 | for (i = -2; i <= 2; i++) | |
21 | assert_se(ordered_hashmap_put(m, INT_TO_PTR(i), INT_TO_PTR(i+10)) == 1); | |
22 | for (i = -2; i <= 1; i++) | |
23 | assert_se(ordered_hashmap_next(m, INT_TO_PTR(i)) == INT_TO_PTR(i+11)); | |
24 | assert_se(!ordered_hashmap_next(m, INT_TO_PTR(2))); | |
25 | assert_se(!ordered_hashmap_next(NULL, INT_TO_PTR(1))); | |
26 | assert_se(!ordered_hashmap_next(m, INT_TO_PTR(3))); | |
d06b3a9d RC |
27 | } |
28 | ||
c462e63e | 29 | TEST(uint64_compare_func) { |
8097ab4f ZJS |
30 | const uint64_t a = 0x100, b = 0x101; |
31 | ||
32 | assert_se(uint64_compare_func(&a, &a) == 0); | |
33 | assert_se(uint64_compare_func(&a, &b) == -1); | |
34 | assert_se(uint64_compare_func(&b, &a) == 1); | |
9341a4a1 DB |
35 | } |
36 | ||
c462e63e | 37 | TEST(trivial_compare_func) { |
9341a4a1 DB |
38 | assert_se(trivial_compare_func(INT_TO_PTR('a'), INT_TO_PTR('a')) == 0); |
39 | assert_se(trivial_compare_func(INT_TO_PTR('a'), INT_TO_PTR('b')) == -1); | |
40 | assert_se(trivial_compare_func(INT_TO_PTR('b'), INT_TO_PTR('a')) == 1); | |
41 | } | |
42 | ||
c462e63e | 43 | TEST(string_compare_func) { |
5f0e4d2f | 44 | ASSERT_NE(string_compare_func("fred", "wilma"), 0); |
9341a4a1 DB |
45 | assert_se(string_compare_func("fred", "fred") == 0); |
46 | } | |
47 | ||
647c7b74 VC |
48 | static void compare_cache(Hashmap *map, IteratedCache *cache) { |
49 | const void **keys = NULL, **values = NULL; | |
50 | unsigned num, idx; | |
647c7b74 VC |
51 | void *k, *v; |
52 | ||
53 | assert_se(iterated_cache_get(cache, &keys, &values, &num) == 0); | |
54 | assert_se(num == 0 || keys); | |
55 | assert_se(num == 0 || values); | |
56 | ||
57 | idx = 0; | |
90e74a66 | 58 | HASHMAP_FOREACH_KEY(v, k, map) { |
647c7b74 VC |
59 | assert_se(v == values[idx]); |
60 | assert_se(k == keys[idx]); | |
61 | ||
62 | idx++; | |
63 | } | |
64 | ||
65 | assert_se(idx == num); | |
66 | } | |
67 | ||
c462e63e | 68 | TEST(iterated_cache) { |
647c7b74 VC |
69 | Hashmap *m; |
70 | IteratedCache *c; | |
71 | ||
72 | assert_se(m = hashmap_new(NULL)); | |
73 | assert_se(c = hashmap_iterated_cache_new(m)); | |
74 | compare_cache(m, c); | |
75 | ||
76 | for (int stage = 0; stage < 100; stage++) { | |
77 | ||
78 | for (int i = 0; i < 100; i++) { | |
79 | int foo = stage * 1000 + i; | |
80 | ||
81 | assert_se(hashmap_put(m, INT_TO_PTR(foo), INT_TO_PTR(foo + 777)) == 1); | |
82 | } | |
83 | ||
84 | compare_cache(m, c); | |
85 | ||
86 | if (!(stage % 10)) { | |
87 | for (int i = 0; i < 100; i++) { | |
88 | int foo = stage * 1000 + i; | |
89 | ||
90 | assert_se(hashmap_remove(m, INT_TO_PTR(foo)) == INT_TO_PTR(foo + 777)); | |
91 | } | |
92 | ||
93 | compare_cache(m, c); | |
94 | } | |
95 | } | |
96 | ||
97 | hashmap_clear(m); | |
98 | compare_cache(m, c); | |
99 | ||
5152b845 IK |
100 | ASSERT_NULL(hashmap_free(m)); |
101 | ASSERT_NULL(iterated_cache_free(c)); | |
647c7b74 VC |
102 | } |
103 | ||
c462e63e | 104 | TEST(hashmap_put_strdup) { |
25b3e2a8 ZJS |
105 | _cleanup_hashmap_free_ Hashmap *m = NULL; |
106 | char *s; | |
107 | ||
108 | /* We don't have ordered_hashmap_put_strdup() yet. If it is added, | |
109 | * these tests should be moved to test-hashmap-plain.c. */ | |
110 | ||
25b3e2a8 ZJS |
111 | assert_se(hashmap_put_strdup(&m, "foo", "bar") == 1); |
112 | assert_se(hashmap_put_strdup(&m, "foo", "bar") == 0); | |
113 | assert_se(hashmap_put_strdup(&m, "foo", "BAR") == -EEXIST); | |
114 | assert_se(hashmap_put_strdup(&m, "foo", "bar") == 0); | |
115 | assert_se(hashmap_contains(m, "foo")); | |
116 | ||
117 | s = hashmap_get(m, "foo"); | |
c79e88b3 | 118 | ASSERT_STREQ(s, "bar"); |
25b3e2a8 ZJS |
119 | |
120 | assert_se(hashmap_put_strdup(&m, "xxx", "bar") == 1); | |
121 | assert_se(hashmap_put_strdup(&m, "xxx", "bar") == 0); | |
122 | assert_se(hashmap_put_strdup(&m, "xxx", "BAR") == -EEXIST); | |
123 | assert_se(hashmap_put_strdup(&m, "xxx", "bar") == 0); | |
124 | assert_se(hashmap_contains(m, "xxx")); | |
125 | ||
126 | s = hashmap_get(m, "xxx"); | |
c79e88b3 | 127 | ASSERT_STREQ(s, "bar"); |
25b3e2a8 ZJS |
128 | } |
129 | ||
c462e63e | 130 | TEST(hashmap_put_strdup_null) { |
25b3e2a8 ZJS |
131 | _cleanup_hashmap_free_ Hashmap *m = NULL; |
132 | char *s; | |
133 | ||
25b3e2a8 ZJS |
134 | assert_se(hashmap_put_strdup(&m, "foo", "bar") == 1); |
135 | assert_se(hashmap_put_strdup(&m, "foo", "bar") == 0); | |
136 | assert_se(hashmap_put_strdup(&m, "foo", NULL) == -EEXIST); | |
137 | assert_se(hashmap_put_strdup(&m, "foo", "bar") == 0); | |
138 | assert_se(hashmap_contains(m, "foo")); | |
139 | ||
140 | s = hashmap_get(m, "foo"); | |
c79e88b3 | 141 | ASSERT_STREQ(s, "bar"); |
25b3e2a8 ZJS |
142 | |
143 | assert_se(hashmap_put_strdup(&m, "xxx", NULL) == 1); | |
144 | assert_se(hashmap_put_strdup(&m, "xxx", "bar") == -EEXIST); | |
145 | assert_se(hashmap_put_strdup(&m, "xxx", NULL) == 0); | |
146 | assert_se(hashmap_contains(m, "xxx")); | |
147 | ||
148 | s = hashmap_get(m, "xxx"); | |
5152b845 | 149 | ASSERT_NULL(s); |
25b3e2a8 ZJS |
150 | } |
151 | ||
c462e63e JJ |
152 | /* This file tests in test-hashmap-plain.c, and tests in test-hashmap-ordered.c, which is generated |
153 | * from test-hashmap-plain.c. Hashmap tests should be added to test-hashmap-plain.c, and here only if | |
154 | * they don't apply to ordered hashmaps. */ | |
46e16b34 | 155 | |
c462e63e JJ |
156 | /* This variable allows us to assert that the tests from different compilation units were actually run. */ |
157 | int n_extern_tests_run = 0; | |
32ca2911 | 158 | |
99839c7e LP |
159 | static int intro(void) { |
160 | assert_se(n_extern_tests_run == 0); | |
161 | return EXIT_SUCCESS; | |
162 | } | |
163 | ||
164 | static int outro(void) { | |
165 | /* Ensure hashmap and ordered_hashmap were tested. */ | |
166 | assert_se(n_extern_tests_run == 2); | |
167 | return EXIT_SUCCESS; | |
168 | } | |
169 | ||
e85fdacc | 170 | DEFINE_TEST_MAIN_FULL(LOG_INFO, intro, outro); |