1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3 * libHashKit Functions Test
5 * Copyright (C) 2011 Data Differential, http://datadifferential.com/
6 * Copyright (C) 2006-2009 Brian Aker All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following disclaimer
17 * in the documentation and/or other materials provided with the
20 * * The names of its contributors may not be used to endorse or
21 * promote products derived from this software without specific prior
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 #include <mem_config.h>
39 #include <libtest/test.hpp>
41 using namespace libtest
;
47 #include <libhashkit-1.0/hashkit.h>
48 #include <libhashkit/is.h>
50 #include "tests/hash_results.h"
52 static hashkit_st global_hashk
;
55 @brief hash_test_st is a structure we use in testing. It is currently empty.
57 typedef struct hash_test_st hash_test_st
;
64 static test_return_t
init_test(void *)
67 hashkit_st
*hashk_ptr
;
69 hashk_ptr
= hashkit_create(&hashk
);
71 test_true(hashk_ptr
== &hashk
);
72 test_false(hashkit_is_allocated(hashk_ptr
));
74 hashkit_free(hashk_ptr
);
79 static test_return_t
allocation_test(void *)
81 hashkit_st
*hashk_ptr
;
83 hashk_ptr
= hashkit_create(NULL
);
85 test_true(hashkit_is_allocated(hashk_ptr
));
86 hashkit_free(hashk_ptr
);
91 static test_return_t
clone_test(hashkit_st
*hashk
)
93 // First we make sure that the testing system is giving us what we expect.
94 test_true(&global_hashk
== hashk
);
96 // Second we test if hashk is even valid
100 hashkit_st
*hashk_ptr
;
101 hashk_ptr
= hashkit_clone(NULL
, NULL
);
102 test_true(hashk_ptr
);
103 test_true(hashkit_is_allocated(hashk_ptr
));
104 hashkit_free(hashk_ptr
);
107 /* Can we init from null? */
109 hashkit_st
*hashk_ptr
;
111 hashk_ptr
= hashkit_clone(NULL
, hashk
);
113 test_true(hashk_ptr
);
114 test_true(hashkit_is_allocated(hashk_ptr
));
116 hashkit_free(hashk_ptr
);
119 /* Can we init from struct? */
121 hashkit_st declared_clone
;
122 hashkit_st
*hash_clone
;
124 hash_clone
= hashkit_clone(&declared_clone
, NULL
);
125 test_true(hash_clone
);
126 test_true(hash_clone
== &declared_clone
);
127 test_false(hashkit_is_allocated(hash_clone
));
129 hashkit_free(hash_clone
);
132 /* Can we init from struct? */
134 hashkit_st declared_clone
;
135 hashkit_st
*hash_clone
;
137 hash_clone
= hashkit_clone(&declared_clone
, hashk
);
138 test_true(hash_clone
);
139 test_true(hash_clone
== &declared_clone
);
140 test_false(hashkit_is_allocated(hash_clone
));
142 hashkit_free(hash_clone
);
148 static test_return_t
one_at_a_time_run (hashkit_st
*)
153 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
155 test_compare(one_at_a_time_values
[x
],
156 libhashkit_one_at_a_time(*ptr
, strlen(*ptr
)));
162 static test_return_t
md5_run (hashkit_st
*)
167 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
169 test_compare(md5_values
[x
],
170 libhashkit_md5(*ptr
, strlen(*ptr
)));
176 static test_return_t
crc_run (hashkit_st
*)
181 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
183 test_compare(crc_values
[x
],
184 libhashkit_crc32(*ptr
, strlen(*ptr
)));
190 static test_return_t
fnv1_64_run (hashkit_st
*)
192 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_FNV1_64
));
197 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
199 test_compare(fnv1_64_values
[x
],
200 libhashkit_fnv1_64(*ptr
, strlen(*ptr
)));
206 static test_return_t
fnv1a_64_run (hashkit_st
*)
208 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_FNV1A_64
));
212 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
214 test_compare(fnv1a_64_values
[x
],
215 libhashkit_fnv1a_64(*ptr
, strlen(*ptr
)));
221 static test_return_t
fnv1_32_run (hashkit_st
*)
226 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
228 test_compare(fnv1_32_values
[x
],
229 libhashkit_fnv1_32(*ptr
, strlen(*ptr
)));
235 static test_return_t
fnv1a_32_run (hashkit_st
*)
240 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
242 test_compare(fnv1a_32_values
[x
],
243 libhashkit_fnv1a_32(*ptr
, strlen(*ptr
)));
249 static test_return_t
hsieh_run (hashkit_st
*)
251 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_HSIEH
));
256 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
258 test_compare(hsieh_values
[x
],
259 libhashkit_hsieh(*ptr
, strlen(*ptr
)));
265 static test_return_t
murmur3_TEST(hashkit_st
*)
267 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR3
));
269 #ifdef WORDS_BIGENDIAN
270 (void)murmur3_values
;
276 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
278 test_compare(murmur3_values
[x
],
279 libhashkit_murmur3(*ptr
, strlen(*ptr
)));
286 static test_return_t
murmur_run (hashkit_st
*)
288 test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR
));
290 #ifdef WORDS_BIGENDIAN
297 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
299 test_compare(murmur_values
[x
],
300 libhashkit_murmur(*ptr
, strlen(*ptr
)));
307 static test_return_t
jenkins_run (hashkit_st
*)
312 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
314 test_compare(jenkins_values
[x
],
315 libhashkit_jenkins(*ptr
, strlen(*ptr
)));
325 @brief now we list out the tests.
328 test_st allocation
[]= {
329 {"init", 0, (test_callback_fn
*)init_test
},
330 {"create and free", 0, (test_callback_fn
*)allocation_test
},
331 {"clone", 0, (test_callback_fn
*)clone_test
},
335 static test_return_t
hashkit_digest_test(hashkit_st
*hashk
)
337 test_true(hashkit_digest(hashk
, "a", sizeof("a")));
342 static test_return_t
hashkit_set_function_test(hashkit_st
*hashk
)
344 for (int algo
= int(HASHKIT_HASH_DEFAULT
); algo
< int(HASHKIT_HASH_MAX
); algo
++)
350 test_skip(true, libhashkit_has_algorithm(static_cast<hashkit_hash_algorithm_t
>(algo
)));
352 hashkit_return_t rc
= hashkit_set_function(hashk
, static_cast<hashkit_hash_algorithm_t
>(algo
));
354 test_compare_got(HASHKIT_SUCCESS
, rc
, hashkit_strerror(NULL
, rc
));
358 case HASHKIT_HASH_DEFAULT
:
359 list
= one_at_a_time_values
;
362 case HASHKIT_HASH_MD5
:
366 case HASHKIT_HASH_CRC
:
370 case HASHKIT_HASH_FNV1_64
:
371 list
= fnv1_64_values
;
374 case HASHKIT_HASH_FNV1A_64
:
375 list
= fnv1a_64_values
;
378 case HASHKIT_HASH_FNV1_32
:
379 list
= fnv1_32_values
;
382 case HASHKIT_HASH_FNV1A_32
:
383 list
= fnv1a_32_values
;
386 case HASHKIT_HASH_HSIEH
:
390 case HASHKIT_HASH_MURMUR
:
394 case HASHKIT_HASH_JENKINS
:
395 list
= jenkins_values
;
398 case HASHKIT_HASH_CUSTOM
:
399 case HASHKIT_HASH_MAX
:
405 // Now we make sure we did set the hash correctly.
408 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
410 test_compare(list
[x
],
411 hashkit_digest(hashk
, *ptr
, strlen(*ptr
)));
423 static uint32_t hash_test_function(const char *string
, size_t string_length
, void *)
425 return libhashkit_md5(string
, string_length
);
428 static test_return_t
hashkit_set_custom_function_test(hashkit_st
*hashk
)
434 test_compare(HASHKIT_SUCCESS
,
435 hashkit_set_custom_function(hashk
, hash_test_function
, NULL
));
437 for (ptr
= list_to_hash
, x
= 0; *ptr
; ptr
++, x
++)
439 test_compare(md5_values
[x
],
440 hashkit_digest(hashk
, *ptr
, strlen(*ptr
)));
446 static test_return_t
hashkit_set_distribution_function_test(hashkit_st
*hashk
)
448 for (int algo
= int(HASHKIT_HASH_DEFAULT
); algo
< int(HASHKIT_HASH_MAX
); algo
++)
450 hashkit_return_t rc
= hashkit_set_distribution_function(hashk
, static_cast<hashkit_hash_algorithm_t
>(algo
));
452 /* Hsieh is disabled most of the time for patent issues */
453 if (rc
== HASHKIT_INVALID_ARGUMENT
)
456 test_compare(HASHKIT_SUCCESS
, rc
);
462 static test_return_t
hashkit_set_custom_distribution_function_test(hashkit_st
*hashk
)
464 test_compare(HASHKIT_SUCCESS
,
465 hashkit_set_custom_distribution_function(hashk
, hash_test_function
, NULL
));
471 static test_return_t
hashkit_get_function_test(hashkit_st
*hashk
)
473 for (int algo
= int(HASHKIT_HASH_DEFAULT
); algo
< int(HASHKIT_HASH_MAX
); algo
++)
476 if (HASHKIT_HASH_CUSTOM
)
480 test_skip(true, libhashkit_has_algorithm(static_cast<hashkit_hash_algorithm_t
>(algo
)));
482 test_compare(HASHKIT_SUCCESS
,
483 hashkit_set_function(hashk
, static_cast<hashkit_hash_algorithm_t
>(algo
)));
485 test_compare(hashkit_get_function(hashk
), algo
);
490 static test_return_t
hashkit_compare_test(hashkit_st
*hashk
)
492 hashkit_st
*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
*)
513 test_true(libhashkit_digest("a", sizeof("a"), HASHKIT_HASH_DEFAULT
));
518 test_st library_functions
[] ={
519 {"libhashkit_digest", 0, (test_callback_fn
*)libhashkit_digest_test
},
523 test_st hash_tests
[] ={
524 {"one_at_a_time", 0, (test_callback_fn
*)one_at_a_time_run
},
525 {"md5", 0, (test_callback_fn
*)md5_run
},
526 {"crc", 0, (test_callback_fn
*)crc_run
},
527 {"fnv1_64", 0, (test_callback_fn
*)fnv1_64_run
},
528 {"fnv1a_64", 0, (test_callback_fn
*)fnv1a_64_run
},
529 {"fnv1_32", 0, (test_callback_fn
*)fnv1_32_run
},
530 {"fnv1a_32", 0, (test_callback_fn
*)fnv1a_32_run
},
531 {"hsieh", 0, (test_callback_fn
*)hsieh_run
},
532 {"murmur", 0, (test_callback_fn
*)murmur_run
},
533 {"murmur3", 0, (test_callback_fn
*)murmur3_TEST
},
534 {"jenkis", 0, (test_callback_fn
*)jenkins_run
},
535 {0, 0, (test_callback_fn
*)0}
539 * The following test suite is used to verify that we don't introduce
540 * regression bugs. If you want more information about the bug / test,
541 * you should look in the bug report at
542 * http://bugs.launchpad.net/libmemcached
544 test_st regression
[]= {
548 collection_st collection
[] ={
549 {"allocation", 0, 0, allocation
},
550 {"hashkit_st_functions", 0, 0, hashkit_st_functions
},
551 {"library_functions", 0, 0, library_functions
},
552 {"hashing", 0, 0, hash_tests
},
553 {"regression", 0, 0, regression
},
557 static void *world_create(libtest::server_startup_st
&, test_return_t
& error
)
559 hashkit_st
*hashk_ptr
= hashkit_create(&global_hashk
);
561 if (hashk_ptr
!= &global_hashk
)
567 if (hashkit_is_allocated(hashk_ptr
) == true)
577 static bool world_destroy(void *object
)
579 hashkit_st
*hashk
= (hashkit_st
*)object
;
580 // Did we get back what we expected?
581 test_true(hashkit_is_allocated(hashk
) == false);
582 hashkit_free(&global_hashk
);
587 void get_world(libtest::Framework
* world
)
589 world
->collections(collection
);
590 world
->create(world_create
);
591 world
->destroy(world_destroy
);