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