1 /* libHashKit Functions Test
2 * Copyright (C) 2006-2009 Brian Aker
5 * Use and distribution licensed under the BSD license. See
6 * the COPYING file in the parent directory for full text.
16 #include <libhashkit/hashkit.h>
20 #include "hash_results.h"
22 static hashkit_st global_hashk
;
25 @brief hash_test_st is a structure we use in testing. It is currently empty.
27 typedef struct hash_test_st hash_test_st
;
34 static test_return_t
init_test(void *not_used
__attribute__((unused
)))
37 hashkit_st
*hashk_ptr
;
39 hashk_ptr
= hashkit_create(&hashk
);
41 test_true(hashk_ptr
== &hashk
);
42 test_true(hashkit_is_allocated(hashk_ptr
) == false);
44 hashkit_free(hashk_ptr
);
49 static test_return_t
allocation_test(void *not_used
__attribute__((unused
)))
51 hashkit_st
*hashk_ptr
;
53 hashk_ptr
= hashkit_create(NULL
);
55 test_true(hashkit_is_allocated(hashk_ptr
) == true);
56 hashkit_free(hashk_ptr
);
61 static test_return_t
clone_test(hashkit_st
*hashk
)
63 // First we make sure that the testing system is giving us what we expect.
64 assert(&global_hashk
== hashk
);
66 // Second we test if hashk is even valid
70 hashkit_st
*hashk_ptr
;
71 hashk_ptr
= hashkit_clone(NULL
, NULL
);
73 test_true(hashkit_is_allocated(hashk_ptr
));
74 hashkit_free(hashk_ptr
);
77 /* Can we init from null? */
79 hashkit_st
*hashk_ptr
;
81 hashk_ptr
= hashkit_clone(NULL
, hashk
);
84 test_true(hashkit_is_allocated(hashk_ptr
));
86 hashkit_free(hashk_ptr
);
89 /* Can we init from struct? */
91 hashkit_st declared_clone
;
92 hashkit_st
*hash_clone
;
94 hash_clone
= hashkit_clone(&declared_clone
, NULL
);
95 test_true(hash_clone
);
96 test_true(hash_clone
== &declared_clone
);
97 test_false(hashkit_is_allocated(hash_clone
));
99 hashkit_free(hash_clone
);
102 /* Can we init from struct? */
104 hashkit_st declared_clone
;
105 hashkit_st
*hash_clone
;
107 hash_clone
= hashkit_clone(&declared_clone
, hashk
);
108 test_true(hash_clone
);
109 test_true(hash_clone
== &declared_clone
);
110 test_false(hashkit_is_allocated(hash_clone
));
112 hashkit_free(hash_clone
);
118 static test_return_t
one_at_a_time_run (hashkit_st
*hashk
__attribute__((unused
)))
123 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
127 hash_val
= libhashkit_one_at_a_time(*ptr
, strlen(*ptr
));
128 test_true(one_at_a_time_values
[x
] == hash_val
);
134 static test_return_t
md5_run (hashkit_st
*hashk
__attribute__((unused
)))
139 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
143 hash_val
= libhashkit_md5(*ptr
, strlen(*ptr
));
144 test_true(md5_values
[x
] == hash_val
);
150 static test_return_t
crc_run (hashkit_st
*hashk
__attribute__((unused
)))
155 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
159 hash_val
= libhashkit_crc32(*ptr
, strlen(*ptr
));
160 assert(crc_values
[x
] == hash_val
);
166 static test_return_t
fnv1_64_run (hashkit_st
*hashk
__attribute__((unused
)))
171 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
175 hash_val
= libhashkit_fnv1_64(*ptr
, strlen(*ptr
));
176 assert(fnv1_64_values
[x
] == hash_val
);
182 static test_return_t
fnv1a_64_run (hashkit_st
*hashk
__attribute__((unused
)))
187 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
191 hash_val
= libhashkit_fnv1a_64(*ptr
, strlen(*ptr
));
192 assert(fnv1a_64_values
[x
] == hash_val
);
198 static test_return_t
fnv1_32_run (hashkit_st
*hashk
__attribute__((unused
)))
204 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
208 hash_val
= libhashkit_fnv1_32(*ptr
, strlen(*ptr
));
209 assert(fnv1_32_values
[x
] == hash_val
);
215 static test_return_t
fnv1a_32_run (hashkit_st
*hashk
__attribute__((unused
)))
220 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
224 hash_val
= libhashkit_fnv1a_32(*ptr
, strlen(*ptr
));
225 assert(fnv1a_32_values
[x
] == hash_val
);
231 static test_return_t
hsieh_run (hashkit_st
*hashk
__attribute__((unused
)))
236 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
240 #ifdef HAVE_HSIEH_HASH
241 hash_val
= libhashkit_hsieh(*ptr
, strlen(*ptr
));
245 assert(hsieh_values
[x
] == hash_val
);
251 static test_return_t
murmur_run (hashkit_st
*hashk
__attribute__((unused
)))
253 #ifdef WORDS_BIGENDIAN
260 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
264 #ifdef HAVE_MURMUR_HASH
265 hash_val
= libhashkit_murmur(*ptr
, strlen(*ptr
));
269 assert(murmur_values
[x
] == hash_val
);
276 static test_return_t
jenkins_run (hashkit_st
*hashk
__attribute__((unused
)))
282 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
286 hash_val
= libhashkit_jenkins(*ptr
, strlen(*ptr
));
287 assert(jenkins_values
[x
] == hash_val
);
297 @brief now we list out the tests.
300 test_st allocation
[]= {
301 {"init", 0, (test_callback_fn
)init_test
},
302 {"create and free", 0, (test_callback_fn
)allocation_test
},
303 {"clone", 0, (test_callback_fn
)clone_test
},
307 static test_return_t
hashkit_digest_test(hashkit_st
*hashk
)
310 value
= hashkit_digest(hashk
, "a", sizeof("a"));
315 static test_return_t
hashkit_set_function_test(hashkit_st
*hashk
)
317 for (hashkit_hash_algorithm_t algo
= HASHKIT_HASH_DEFAULT
; algo
< HASHKIT_HASH_MAX
; algo
++)
324 rc
= hashkit_set_function(hashk
, algo
);
326 /* Hsieh is disabled most of the time for patent issues */
327 #ifndef HAVE_HSIEH_HASH
328 if (rc
== HASHKIT_FAILURE
&& algo
== HASHKIT_HASH_HSIEH
)
332 #ifndef HAVE_MURMUR_HASH
333 if (rc
== HASHKIT_FAILURE
&& algo
== HASHKIT_HASH_MURMUR
)
337 if (rc
== HASHKIT_FAILURE
&& algo
== HASHKIT_HASH_CUSTOM
)
340 test_true(rc
== HASHKIT_SUCCESS
);
344 case HASHKIT_HASH_DEFAULT
:
345 list
= one_at_a_time_values
;
347 case HASHKIT_HASH_MD5
:
350 case HASHKIT_HASH_CRC
:
353 case HASHKIT_HASH_FNV1_64
:
354 list
= fnv1_64_values
;
356 case HASHKIT_HASH_FNV1A_64
:
357 list
= fnv1a_64_values
;
359 case HASHKIT_HASH_FNV1_32
:
360 list
= fnv1_32_values
;
362 case HASHKIT_HASH_FNV1A_32
:
363 list
= fnv1a_32_values
;
365 case HASHKIT_HASH_HSIEH
:
368 case HASHKIT_HASH_MURMUR
:
371 case HASHKIT_HASH_JENKINS
:
372 list
= jenkins_values
;
374 case HASHKIT_HASH_CUSTOM
:
375 case HASHKIT_HASH_MAX
:
381 // Now we make sure we did set the hash correctly.
384 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
388 hash_val
= hashkit_digest(hashk
, *ptr
, strlen(*ptr
));
389 test_true(list
[x
] == hash_val
);
401 static uint32_t hash_test_function(const char *string
, size_t string_length
, void *context
)
404 return libhashkit_md5(string
, string_length
);
407 static test_return_t
hashkit_set_custom_function_test(hashkit_st
*hashk
)
414 rc
= hashkit_set_custom_function(hashk
, hash_test_function
, NULL
);
415 test_true(rc
== HASHKIT_SUCCESS
);
417 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
421 hash_val
= hashkit_digest(hashk
, *ptr
, strlen(*ptr
));
422 test_true(md5_values
[x
] == hash_val
);
428 static test_return_t
hashkit_set_distribution_function_test(hashkit_st
*hashk
)
430 for (hashkit_hash_algorithm_t algo
= HASHKIT_HASH_DEFAULT
; algo
< HASHKIT_HASH_MAX
; algo
++)
434 rc
= hashkit_set_distribution_function(hashk
, algo
);
436 /* Hsieh is disabled most of the time for patent issues */
437 if (rc
== HASHKIT_FAILURE
&& algo
== HASHKIT_HASH_HSIEH
)
440 if (rc
== HASHKIT_FAILURE
&& algo
== HASHKIT_HASH_CUSTOM
)
443 test_true(rc
== HASHKIT_SUCCESS
);
449 static test_return_t
hashkit_set_custom_distribution_function_test(hashkit_st
*hashk
)
453 rc
= hashkit_set_custom_distribution_function(hashk
, hash_test_function
, NULL
);
454 test_true(rc
== HASHKIT_SUCCESS
);
460 static test_return_t
hashkit_get_function_test(hashkit_st
*hashk
)
462 for (hashkit_hash_algorithm_t algo
= HASHKIT_HASH_DEFAULT
; algo
< HASHKIT_HASH_MAX
; algo
++)
466 if (HASHKIT_HASH_CUSTOM
|| HASHKIT_HASH_HSIEH
)
469 rc
= hashkit_set_function(hashk
, algo
);
470 test_true(rc
== HASHKIT_SUCCESS
);
472 test_true(hashkit_get_function(hashk
) == algo
);
477 static test_return_t
hashkit_compare_test(hashkit_st
*hashk
)
481 clone
= hashkit_clone(NULL
, hashk
);
483 test_true(hashkit_compare(clone
, hashk
));
489 test_st hashkit_st_functions
[] ={
490 {"hashkit_digest", 0, (test_callback_fn
)hashkit_digest_test
},
491 {"hashkit_set_function", 0, (test_callback_fn
)hashkit_set_function_test
},
492 {"hashkit_set_custom_function", 0, (test_callback_fn
)hashkit_set_custom_function_test
},
493 {"hashkit_get_function", 0, (test_callback_fn
)hashkit_get_function_test
},
494 {"hashkit_set_distribution_function", 0, (test_callback_fn
)hashkit_set_distribution_function_test
},
495 {"hashkit_set_custom_distribution_function", 0, (test_callback_fn
)hashkit_set_custom_distribution_function_test
},
496 {"hashkit_compare", 0, (test_callback_fn
)hashkit_compare_test
},
500 static test_return_t
libhashkit_digest_test(hashkit_st
*hashk
)
506 value
= libhashkit_digest("a", sizeof("a"), HASHKIT_HASH_DEFAULT
);
511 test_st library_functions
[] ={
512 {"libhashkit_digest", 0, (test_callback_fn
)libhashkit_digest_test
},
516 test_st hash_tests
[] ={
517 {"one_at_a_time", 0, (test_callback_fn
)one_at_a_time_run
},
518 {"md5", 0, (test_callback_fn
)md5_run
},
519 {"crc", 0, (test_callback_fn
)crc_run
},
520 {"fnv1_64", 0, (test_callback_fn
)fnv1_64_run
},
521 {"fnv1a_64", 0, (test_callback_fn
)fnv1a_64_run
},
522 {"fnv1_32", 0, (test_callback_fn
)fnv1_32_run
},
523 {"fnv1a_32", 0, (test_callback_fn
)fnv1a_32_run
},
524 {"hsieh", 0, (test_callback_fn
)hsieh_run
},
525 {"murmur", 0, (test_callback_fn
)murmur_run
},
526 {"jenkis", 0, (test_callback_fn
)jenkins_run
},
527 {0, 0, (test_callback_fn
)0}
531 * The following test suite is used to verify that we don't introduce
532 * regression bugs. If you want more information about the bug / test,
533 * you should look in the bug report at
534 * http://bugs.launchpad.net/libmemcached
536 test_st regression
[]= {
540 collection_st collection
[] ={
541 {"allocation", 0, 0, allocation
},
542 {"hashkit_st_functions", 0, 0, hashkit_st_functions
},
543 {"library_functions", 0, 0, library_functions
},
544 {"hashing", 0, 0, hash_tests
},
545 {"regression", 0, 0, regression
},
549 /* Prototypes for functions we will pass to test framework */
550 void *world_create(test_return_t
*error
);
551 test_return_t
world_destroy(hashkit_st
*hashk
);
553 void *world_create(test_return_t
*error
)
555 hashkit_st
*hashk_ptr
;
557 hashk_ptr
= hashkit_create(&global_hashk
);
559 if (hashk_ptr
!= &global_hashk
)
561 *error
= TEST_FAILURE
;
565 if (hashkit_is_allocated(hashk_ptr
) == true)
567 *error
= TEST_FAILURE
;
571 *error
= TEST_SUCCESS
;
577 test_return_t
world_destroy(hashkit_st
*hashk
)
579 // Did we get back what we expected?
580 assert(hashkit_is_allocated(hashk
) == false);
581 hashkit_free(&global_hashk
);
586 void get_world(world_st
*world
)
588 world
->collections
= collection
;
589 world
->create
= (test_callback_create_fn
)world_create
;
590 world
->destroy
= (test_callback_fn
)world_destroy
;