2 * Copyright (C) 2014 Intel Corporation. All rights reserved.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 #include <shared/hash.h>
26 #include <shared/util.h>
28 #include "testsuite.h"
32 static void countfreecalls(void *v
)
37 static int test_hash_new(const struct test
*t
)
39 struct hash
*h
= hash_new(8, NULL
);
40 assert_return(h
!= NULL
, EXIT_FAILURE
);
44 DEFINE_TEST(test_hash_new
,
45 .description
= "test hash_new");
48 static int test_hash_get_count(const struct test
*t
)
50 struct hash
*h
= hash_new(8, NULL
);
51 const char *k1
= "k1", *k2
= "k2", *k3
= "k3";
52 const char *v1
= "v1", *v2
= "v2", *v3
= "v3";
58 assert_return(hash_get_count(h
) == 3, EXIT_FAILURE
);
63 DEFINE_TEST(test_hash_get_count
,
64 .description
= "test hash_add / hash_get_count");
67 static int test_hash_replace(const struct test
*t
)
69 struct hash
*h
= hash_new(8, countfreecalls
);
70 const char *k1
= "k1", *k2
= "k2", *k3
= "k3";
71 const char *v1
= "v1", *v2
= "v2", *v3
= "v3", *v4
= "v4";
75 r
|= hash_add(h
, k1
, v1
);
76 r
|= hash_add(h
, k2
, v2
);
77 r
|= hash_add(h
, k3
, v3
);
80 r
|= hash_add(h
, k1
, v4
);
82 assert_return(r
== 0, EXIT_FAILURE
);
83 assert_return(hash_get_count(h
) == 3, EXIT_FAILURE
);
85 v
= hash_find(h
, "k1");
86 assert_return(streq(v
, v4
), EXIT_FAILURE
);
88 assert_return(freecount
== 1, EXIT_FAILURE
);
93 DEFINE_TEST(test_hash_replace
,
94 .description
= "test hash_add replacing existing value");
97 static int test_hash_replace_failing(const struct test
*t
)
99 struct hash
*h
= hash_new(8, countfreecalls
);
100 const char *k1
= "k1", *k2
= "k2", *k3
= "k3";
101 const char *v1
= "v1", *v2
= "v2", *v3
= "v3", *v4
= "v4";
105 r
|= hash_add(h
, k1
, v1
);
106 r
|= hash_add(h
, k2
, v2
);
107 r
|= hash_add(h
, k3
, v3
);
109 assert_return(r
== 0, EXIT_FAILURE
);
112 r
= hash_add_unique(h
, k1
, v4
);
113 assert_return(r
!= 0, EXIT_FAILURE
);
114 assert_return(hash_get_count(h
) == 3, EXIT_FAILURE
);
116 v
= hash_find(h
, "k1");
117 assert_return(streq(v
, v1
), EXIT_FAILURE
);
119 assert_return(freecount
== 0, EXIT_FAILURE
);
124 DEFINE_TEST(test_hash_replace_failing
,
125 .description
= "test hash_add_unique failing to replace existing value");
128 static int test_hash_iter(const struct test
*t
)
130 struct hash
*h
= hash_new(8, NULL
);
131 struct hash
*h2
= hash_new(8, NULL
);
132 const char *k1
= "k1", *k2
= "k2", *k3
= "k3";
133 const char *v1
= "v1", *v2
= "v2", *v3
= "v3";
134 struct hash_iter iter
;
138 hash_add(h2
, k1
, v1
);
140 hash_add(h2
, k2
, v2
);
142 hash_add(h2
, k3
, v3
);
144 for (hash_iter_init(h
, &iter
);
145 hash_iter_next(&iter
, &k
, (const void **) &v
);) {
146 v2
= hash_find(h2
, k
);
147 assert_return(v2
!= NULL
, EXIT_FAILURE
);
151 assert_return(hash_get_count(h
) == 3, EXIT_FAILURE
);
152 assert_return(hash_get_count(h2
) == 0, EXIT_FAILURE
);
158 DEFINE_TEST(test_hash_iter
,
159 .description
= "test hash_iter");
162 static int test_hash_iter_after_del(const struct test
*t
)
164 struct hash
*h
= hash_new(8, NULL
);
165 struct hash
*h2
= hash_new(8, NULL
);
166 const char *k1
= "k1", *k2
= "k2", *k3
= "k3";
167 const char *v1
= "v1", *v2
= "v2", *v3
= "v3";
168 struct hash_iter iter
;
172 hash_add(h2
, k1
, v1
);
174 hash_add(h2
, k2
, v2
);
176 hash_add(h2
, k3
, v3
);
180 for (hash_iter_init(h
, &iter
);
181 hash_iter_next(&iter
, &k
, (const void **) &v
);) {
182 v2
= hash_find(h2
, k
);
183 assert_return(v2
!= NULL
, EXIT_FAILURE
);
187 assert_return(hash_get_count(h
) == 2, EXIT_FAILURE
);
188 assert_return(hash_get_count(h2
) == 1, EXIT_FAILURE
);
194 DEFINE_TEST(test_hash_iter_after_del
,
195 .description
= "test hash_iter, after deleting element");
198 static int test_hash_free(const struct test
*t
)
200 struct hash
*h
= hash_new(8, countfreecalls
);
201 const char *k1
= "k1", *k2
= "k2", *k3
= "k3";
202 const char *v1
= "v1", *v2
= "v2", *v3
= "v3";
210 assert_return(freecount
== 1, EXIT_FAILURE
);
212 assert_return(hash_get_count(h
) == 2, EXIT_FAILURE
);
216 assert_return(freecount
== 3, EXIT_FAILURE
);
220 DEFINE_TEST(test_hash_free
,
221 .description
= "test hash_free calling free function for all values");
224 static int test_hash_add_unique(const struct test
*t
)
226 const char *k
[] = { "k1", "k2", "k3", "k4", "k5" };
227 const char *v
[] = { "v1", "v2", "v3", "v4", "v5" };
228 unsigned int i
, j
, N
;
231 for (i
= 0; i
< N
; i
++) {
232 /* With N - 1 buckets, there'll be a bucket with more than one key. */
233 struct hash
*h
= hash_new(N
- 1, NULL
);
235 /* Add the keys in different orders. */
236 for (j
= 0; j
< N
; j
++) {
237 unsigned int idx
= (j
+ i
) % N
;
238 hash_add_unique(h
, k
[idx
], v
[idx
]);
241 assert_return(hash_get_count(h
) == N
, EXIT_FAILURE
);
246 DEFINE_TEST(test_hash_add_unique
,
247 .description
= "test hash_add_unique with different key orders")
250 static int test_hash_massive_add_del(const struct test
*t
)
255 unsigned int i
, N
= 1024;
257 h
= hash_new(8, NULL
);
260 for (i
= 0; i
< N
; i
++) {
261 snprintf(k
, 8, "k%d", i
);
266 assert_return(hash_get_count(h
) == N
, EXIT_FAILURE
);
269 for (i
= 0; i
< N
; i
++) {
274 assert_return(hash_get_count(h
) == 0, EXIT_FAILURE
);
279 DEFINE_TEST(test_hash_massive_add_del
,
280 .description
= "test multiple adds followed by multiple dels")