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>
18 #include <libtest/test.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
)
37 hashkit_st
*hashk_ptr
;
40 hashk_ptr
= hashkit_create(&hashk
);
42 test_true(hashk_ptr
== &hashk
);
43 test_true(hashkit_is_allocated(hashk_ptr
) == false);
45 hashkit_free(hashk_ptr
);
50 static test_return_t
allocation_test(void *not_used
)
52 hashkit_st
*hashk_ptr
;
55 hashk_ptr
= hashkit_create(NULL
);
57 test_true(hashkit_is_allocated(hashk_ptr
) == true);
58 hashkit_free(hashk_ptr
);
63 static test_return_t
clone_test(hashkit_st
*hashk
)
65 // First we make sure that the testing system is giving us what we expect.
66 assert(&global_hashk
== hashk
);
68 // Second we test if hashk is even valid
72 hashkit_st
*hashk_ptr
;
73 hashk_ptr
= hashkit_clone(NULL
, NULL
);
75 test_true(hashkit_is_allocated(hashk_ptr
));
76 hashkit_free(hashk_ptr
);
79 /* Can we init from null? */
81 hashkit_st
*hashk_ptr
;
83 hashk_ptr
= hashkit_clone(NULL
, hashk
);
86 test_true(hashkit_is_allocated(hashk_ptr
));
88 hashkit_free(hashk_ptr
);
91 /* Can we init from struct? */
93 hashkit_st declared_clone
;
94 hashkit_st
*hash_clone
;
96 hash_clone
= hashkit_clone(&declared_clone
, NULL
);
97 test_true(hash_clone
);
98 test_true(hash_clone
== &declared_clone
);
99 test_false(hashkit_is_allocated(hash_clone
));
101 hashkit_free(hash_clone
);
104 /* Can we init from struct? */
106 hashkit_st declared_clone
;
107 hashkit_st
*hash_clone
;
109 hash_clone
= hashkit_clone(&declared_clone
, hashk
);
110 test_true(hash_clone
);
111 test_true(hash_clone
== &declared_clone
);
112 test_false(hashkit_is_allocated(hash_clone
));
114 hashkit_free(hash_clone
);
120 static test_return_t
one_at_a_time_run (hashkit_st
*hashk
)
126 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
130 hash_val
= libhashkit_one_at_a_time(*ptr
, strlen(*ptr
));
131 test_true(one_at_a_time_values
[x
] == hash_val
);
137 static test_return_t
md5_run (hashkit_st
*hashk
)
143 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
147 hash_val
= libhashkit_md5(*ptr
, strlen(*ptr
));
148 test_true(md5_values
[x
] == hash_val
);
154 static test_return_t
crc_run (hashkit_st
*hashk
)
160 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
164 hash_val
= libhashkit_crc32(*ptr
, strlen(*ptr
));
165 assert(crc_values
[x
] == hash_val
);
171 static test_return_t
fnv1_64_run (hashkit_st
*hashk
)
177 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
181 hash_val
= libhashkit_fnv1_64(*ptr
, strlen(*ptr
));
182 assert(fnv1_64_values
[x
] == hash_val
);
188 static test_return_t
fnv1a_64_run (hashkit_st
*hashk
)
194 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
198 hash_val
= libhashkit_fnv1a_64(*ptr
, strlen(*ptr
));
199 assert(fnv1a_64_values
[x
] == hash_val
);
205 static test_return_t
fnv1_32_run (hashkit_st
*hashk
)
211 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
215 hash_val
= libhashkit_fnv1_32(*ptr
, strlen(*ptr
));
216 assert(fnv1_32_values
[x
] == hash_val
);
222 static test_return_t
fnv1a_32_run (hashkit_st
*hashk
)
228 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
232 hash_val
= libhashkit_fnv1a_32(*ptr
, strlen(*ptr
));
233 assert(fnv1a_32_values
[x
] == hash_val
);
239 static test_return_t
hsieh_run (hashkit_st
*hashk
)
245 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
249 #ifdef HAVE_HSIEH_HASH
250 hash_val
= libhashkit_hsieh(*ptr
, strlen(*ptr
));
254 assert(hsieh_values
[x
] == hash_val
);
260 static test_return_t
murmur_run (hashkit_st
*hashk
)
264 #ifdef WORDS_BIGENDIAN
271 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
275 #ifdef HAVE_MURMUR_HASH
276 hash_val
= libhashkit_murmur(*ptr
, strlen(*ptr
));
280 assert(murmur_values
[x
] == hash_val
);
287 static test_return_t
jenkins_run (hashkit_st
*hashk
)
293 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
297 hash_val
= libhashkit_jenkins(*ptr
, strlen(*ptr
));
298 assert(jenkins_values
[x
] == hash_val
);
308 @brief now we list out the tests.
311 test_st allocation
[]= {
312 {"init", 0, (test_callback_fn
)init_test
},
313 {"create and free", 0, (test_callback_fn
)allocation_test
},
314 {"clone", 0, (test_callback_fn
)clone_test
},
318 static test_return_t
hashkit_digest_test(hashkit_st
*hashk
)
321 value
= hashkit_digest(hashk
, "a", sizeof("a"));
326 static test_return_t
hashkit_set_function_test(hashkit_st
*hashk
)
328 for (hashkit_hash_algorithm_t algo
= HASHKIT_HASH_DEFAULT
; algo
< HASHKIT_HASH_MAX
; algo
++)
335 rc
= hashkit_set_function(hashk
, algo
);
337 /* Hsieh is disabled most of the time for patent issues */
338 #ifndef HAVE_HSIEH_HASH
339 if (rc
== HASHKIT_FAILURE
&& algo
== HASHKIT_HASH_HSIEH
)
343 #ifndef HAVE_MURMUR_HASH
344 if (rc
== HASHKIT_FAILURE
&& algo
== HASHKIT_HASH_MURMUR
)
348 if (rc
== HASHKIT_INVALID_ARGUMENT
&& algo
== HASHKIT_HASH_CUSTOM
)
351 test_true_got(rc
== HASHKIT_SUCCESS
, hashkit_strerror(NULL
, rc
));
355 case HASHKIT_HASH_DEFAULT
:
356 list
= one_at_a_time_values
;
358 case HASHKIT_HASH_MD5
:
361 case HASHKIT_HASH_CRC
:
364 case HASHKIT_HASH_FNV1_64
:
365 list
= fnv1_64_values
;
367 case HASHKIT_HASH_FNV1A_64
:
368 list
= fnv1a_64_values
;
370 case HASHKIT_HASH_FNV1_32
:
371 list
= fnv1_32_values
;
373 case HASHKIT_HASH_FNV1A_32
:
374 list
= fnv1a_32_values
;
376 case HASHKIT_HASH_HSIEH
:
379 case HASHKIT_HASH_MURMUR
:
382 case HASHKIT_HASH_JENKINS
:
383 list
= jenkins_values
;
385 case HASHKIT_HASH_CUSTOM
:
386 case HASHKIT_HASH_MAX
:
392 // Now we make sure we did set the hash correctly.
395 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
399 hash_val
= hashkit_digest(hashk
, *ptr
, strlen(*ptr
));
400 test_true(list
[x
] == hash_val
);
412 static uint32_t hash_test_function(const char *string
, size_t string_length
, void *context
)
415 return libhashkit_md5(string
, string_length
);
418 static test_return_t
hashkit_set_custom_function_test(hashkit_st
*hashk
)
425 rc
= hashkit_set_custom_function(hashk
, hash_test_function
, NULL
);
426 test_true(rc
== HASHKIT_SUCCESS
);
428 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
432 hash_val
= hashkit_digest(hashk
, *ptr
, strlen(*ptr
));
433 test_true(md5_values
[x
] == hash_val
);
439 static test_return_t
hashkit_set_distribution_function_test(hashkit_st
*hashk
)
441 for (hashkit_hash_algorithm_t algo
= HASHKIT_HASH_DEFAULT
; algo
< HASHKIT_HASH_MAX
; algo
++)
445 rc
= hashkit_set_distribution_function(hashk
, algo
);
447 /* Hsieh is disabled most of the time for patent issues */
448 if (rc
== HASHKIT_FAILURE
&& algo
== HASHKIT_HASH_HSIEH
)
451 if (rc
== HASHKIT_INVALID_ARGUMENT
&& algo
== HASHKIT_HASH_CUSTOM
)
454 test_true(rc
== HASHKIT_SUCCESS
);
460 static test_return_t
hashkit_set_custom_distribution_function_test(hashkit_st
*hashk
)
464 rc
= hashkit_set_custom_distribution_function(hashk
, hash_test_function
, NULL
);
465 test_true(rc
== HASHKIT_SUCCESS
);
471 static test_return_t
hashkit_get_function_test(hashkit_st
*hashk
)
473 for (hashkit_hash_algorithm_t algo
= HASHKIT_HASH_DEFAULT
; algo
< HASHKIT_HASH_MAX
; algo
++)
477 if (HASHKIT_HASH_CUSTOM
|| HASHKIT_HASH_HSIEH
)
480 rc
= hashkit_set_function(hashk
, algo
);
481 test_true(rc
== HASHKIT_SUCCESS
);
483 test_true(hashkit_get_function(hashk
) == algo
);
488 static test_return_t
hashkit_compare_test(hashkit_st
*hashk
)
492 clone
= hashkit_clone(NULL
, hashk
);
494 test_true(hashkit_compare(clone
, hashk
));
500 test_st hashkit_st_functions
[] ={
501 {"hashkit_digest", 0, (test_callback_fn
)hashkit_digest_test
},
502 {"hashkit_set_function", 0, (test_callback_fn
)hashkit_set_function_test
},
503 {"hashkit_set_custom_function", 0, (test_callback_fn
)hashkit_set_custom_function_test
},
504 {"hashkit_get_function", 0, (test_callback_fn
)hashkit_get_function_test
},
505 {"hashkit_set_distribution_function", 0, (test_callback_fn
)hashkit_set_distribution_function_test
},
506 {"hashkit_set_custom_distribution_function", 0, (test_callback_fn
)hashkit_set_custom_distribution_function_test
},
507 {"hashkit_compare", 0, (test_callback_fn
)hashkit_compare_test
},
511 static test_return_t
libhashkit_digest_test(hashkit_st
*hashk
)
517 value
= libhashkit_digest("a", sizeof("a"), HASHKIT_HASH_DEFAULT
);
522 test_st library_functions
[] ={
523 {"libhashkit_digest", 0, (test_callback_fn
)libhashkit_digest_test
},
527 test_st hash_tests
[] ={
528 {"one_at_a_time", 0, (test_callback_fn
)one_at_a_time_run
},
529 {"md5", 0, (test_callback_fn
)md5_run
},
530 {"crc", 0, (test_callback_fn
)crc_run
},
531 {"fnv1_64", 0, (test_callback_fn
)fnv1_64_run
},
532 {"fnv1a_64", 0, (test_callback_fn
)fnv1a_64_run
},
533 {"fnv1_32", 0, (test_callback_fn
)fnv1_32_run
},
534 {"fnv1a_32", 0, (test_callback_fn
)fnv1a_32_run
},
535 {"hsieh", 0, (test_callback_fn
)hsieh_run
},
536 {"murmur", 0, (test_callback_fn
)murmur_run
},
537 {"jenkis", 0, (test_callback_fn
)jenkins_run
},
538 {0, 0, (test_callback_fn
)0}
542 * The following test suite is used to verify that we don't introduce
543 * regression bugs. If you want more information about the bug / test,
544 * you should look in the bug report at
545 * http://bugs.launchpad.net/libmemcached
547 test_st regression
[]= {
551 collection_st collection
[] ={
552 {"allocation", 0, 0, allocation
},
553 {"hashkit_st_functions", 0, 0, hashkit_st_functions
},
554 {"library_functions", 0, 0, library_functions
},
555 {"hashing", 0, 0, hash_tests
},
556 {"regression", 0, 0, regression
},
560 /* Prototypes for functions we will pass to test framework */
561 void *world_create(test_return_t
*error
);
562 test_return_t
world_destroy(hashkit_st
*hashk
);
564 void *world_create(test_return_t
*error
)
566 hashkit_st
*hashk_ptr
;
568 hashk_ptr
= hashkit_create(&global_hashk
);
570 if (hashk_ptr
!= &global_hashk
)
572 *error
= TEST_FAILURE
;
576 if (hashkit_is_allocated(hashk_ptr
) == true)
578 *error
= TEST_FAILURE
;
582 *error
= TEST_SUCCESS
;
588 test_return_t
world_destroy(hashkit_st
*hashk
)
590 // Did we get back what we expected?
591 assert(hashkit_is_allocated(hashk
) == false);
592 hashkit_free(&global_hashk
);
597 void get_world(world_st
*world
)
599 world
->collections
= collection
;
600 world
->create
= (test_callback_create_fn
)world_create
;
601 world
->destroy
= (test_callback_fn
)world_destroy
;