summaryrefslogtreecommitdiff
path: root/test_mmh3.c
diff options
context:
space:
mode:
Diffstat (limited to 'test_mmh3.c')
-rw-r--r--test_mmh3.c173
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;
+}