diff options
Diffstat (limited to 'test_mmh3.c')
| -rw-r--r-- | test_mmh3.c | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/test_mmh3.c b/test_mmh3.c new file mode 100644 index 0000000..8946f70 --- /dev/null +++ b/test_mmh3.c @@ -0,0 +1,173 @@ +#include <inttypes.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#include "mmh3.h" + +typedef struct { + const char *name; + const void *data; + size_t len; + uint64_t seed; + uint64_t expected0; + uint64_t expected1; +} test_vector; + +static int +test_mmh3_128_vector(const test_vector *test) +{ + uint64_t out[2] = {0, 0}; + + mmh3_128( + test->data, + test->len, + test->seed, + out + ); + + if (out[0] != test->expected0 || + out[1] != test->expected1) { + + fprintf( + stderr, + "FAIL: %s\n" + " expected: %016" PRIx64 " %016" PRIx64 "\n" + " actual: %016" PRIx64 " %016" PRIx64 "\n", + test->name, + test->expected0, + test->expected1, + out[0], + out[1] + ); + + return 1; + } + + printf("PASS: %s\n", test->name); + return 0; +} + +static int +test_mmh3_128_unaligned(void) +{ + static const char text[] = + "The quick brown fox jumps over the lazy dog"; + + uint8_t buffer[sizeof(text) + 1]; + + /* + * Force the input to begin at an address offset by one byte. + * This catches implementations that incorrectly cast arbitrary + * byte pointers to uint64_t * and perform aligned word reads. + */ + memcpy(buffer + 1, text, sizeof(text) - 1); + + const test_vector test = { + .name = "x64_128 unaligned input", + .data = buffer + 1, + .len = sizeof(text) - 1, + .seed = 0, + .expected0 = UINT64_C(0xe34bbc7bbc071b6c), + .expected1 = UINT64_C(0x7a433ca9c49a9347), + }; + + return test_mmh3_128_vector(&test); +} + + +int +main(void) +{ + static const char empty[] = ""; + static const char foo[] = "foo"; + static const char hello[] = "hello"; + static const char block16[] = "0123456789abcdef"; + static const char block17[] = "0123456789abcdefg"; + static const char quickfox[] = + "The quick brown fox jumps over the lazy dog"; + + static const test_vector tests[] = { + { + .name = "x64_128 empty, seed 0", + .data = empty, + .len = 0, + .seed = 0, + .expected0 = UINT64_C(0x0000000000000000), + .expected1 = UINT64_C(0x0000000000000000), + }, + { + .name = "x64_128 foo, seed 0", + .data = foo, + .len = sizeof(foo) - 1, + .seed = 0, + .expected0 = UINT64_C(0xe271865701f54561), + .expected1 = UINT64_C(0x7eaf87e42bba7d87), + }, + { + .name = "x64_128 hello, seed 0", + .data = hello, + .len = sizeof(hello) - 1, + .seed = 0, + .expected0 = UINT64_C(0xcbd8a7b341bd9b02), + .expected1 = UINT64_C(0x5b1e906a48ae1d19), + }, + { + .name = "x64_128 exactly 16 bytes", + .data = block16, + .len = sizeof(block16) - 1, + .seed = 0, + .expected0 = UINT64_C(0x4be06d94cf4ad1a7), + .expected1 = UINT64_C(0x87c35b5c63a708da), + }, + { + .name = "x64_128 17 bytes", + .data = block17, + .len = sizeof(block17) - 1, + .seed = 0, + .expected0 = UINT64_C(0x8e32612daa45f9de), + .expected1 = UINT64_C(0x0800f4c206c372ee), + }, + { + .name = "x64_128 quick fox, seed 0", + .data = quickfox, + .len = sizeof(quickfox) - 1, + .seed = 0, + .expected0 = UINT64_C(0xe34bbc7bbc071b6c), + .expected1 = UINT64_C(0x7a433ca9c49a9347), + }, + { + .name = "x64_128 foo, seed 42", + .data = foo, + .len = sizeof(foo) - 1, + .seed = 42, + .expected0 = UINT64_C(0xf4569d51637053f2), + .expected1 = UINT64_C(0xa279b5d8eeb09aa9), + }, + }; + + int failures = 0; + + for (size_t i = 0; + i < sizeof(tests) / sizeof(tests[0]); + i++) { + + failures += test_mmh3_128_vector(&tests[i]); + } + + failures += test_mmh3_128_unaligned(); + + if (failures != 0) { + fprintf( + stderr, + "\n%d test%s failed\n", + failures, + failures == 1 ? "" : "s" + ); + + return 1; + } + + printf("\nAll mmh3 tests passed.\n"); + return 0; +} |
