From 39fd73fe171c06f9eb58e107d5d5242114b43539 Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Thu, 30 May 2024 18:05:09 +0200 Subject: [PATCH] Port `testing\core\hash` --- tests/core/Makefile | 2 +- tests/core/build.bat | 2 +- tests/core/hash/test_core_hash.odin | 604 +++++++++++------------ tests/core/hash/test_vectors_xxhash.odin | 6 +- 4 files changed, 302 insertions(+), 312 deletions(-) diff --git a/tests/core/Makefile b/tests/core/Makefile index bc574b004..873bd24af 100644 --- a/tests/core/Makefile +++ b/tests/core/Makefile @@ -60,7 +60,7 @@ fmt_test: $(ODIN) test fmt $(COMMON) -out:test_core_fmt hash_test: - $(ODIN) run hash $(COMMON) -o:speed -out:test_hash + $(ODIN) test hash $(COMMON) -o:speed -out:test_hash i18n_test: $(ODIN) run text/i18n $(COMMON) -out:test_core_i18n diff --git a/tests/core/build.bat b/tests/core/build.bat index aa307672b..4748c3071 100644 --- a/tests/core/build.bat +++ b/tests/core/build.bat @@ -47,7 +47,7 @@ echo --- echo --- echo Running core:hash tests echo --- -%PATH_TO_ODIN% run hash %COMMON% -o:size -out:test_core_hash.exe || exit /b +%PATH_TO_ODIN% test hash %COMMON% -o:speed -out:test_core_hash.exe || exit /b echo --- echo Running core:image tests diff --git a/tests/core/hash/test_core_hash.odin b/tests/core/hash/test_core_hash.odin index 932d2f34c..a6294de55 100644 --- a/tests/core/hash/test_core_hash.odin +++ b/tests/core/hash/test_core_hash.odin @@ -5,47 +5,314 @@ import "core:hash" import "core:time" import "core:testing" import "core:fmt" -import "core:os" +import "core:log" import "core:math/rand" import "base:intrinsics" -TEST_count := 0 -TEST_fail := 0 +@test +test_xxhash_zero_fixed :: proc(t: ^testing.T) { + many_zeroes := make([]u8, 16 * 1024 * 1024) + defer delete(many_zeroes) -when ODIN_TEST { - expect :: testing.expect - log :: testing.log -} else { - expect :: proc(t: ^testing.T, condition: bool, message: string, loc := #caller_location) { - TEST_count += 1 - if !condition { - TEST_fail += 1 - fmt.printf("[%v] %v\n", loc, message) - return + // All at once. + for i, v in ZERO_VECTORS { + b := many_zeroes[:i] + + xxh32 := xxhash.XXH32(b) + xxh64 := xxhash.XXH64(b) + xxh3_64 := xxhash.XXH3_64(b) + xxh3_128 := xxhash.XXH3_128(b) + + testing.expectf(t, xxh32 == v.xxh_32, "[ XXH32(%03d) ] Expected: %08x, got: %08x", i, v.xxh_32, xxh32) + testing.expectf(t, xxh64 == v.xxh_64, "[ XXH64(%03d) ] Expected: %16x, got: %16x", i, v.xxh_64, xxh64) + testing.expectf(t, xxh3_64 == v.xxh3_64, "[XXH3_64(%03d) ] Expected: %16x, got: %16x", i, v.xxh3_64, xxh3_64) + testing.expectf(t, xxh3_128 == v.xxh3_128, "[XXH3_128(%03d) ] Expected: %32x, got: %32x", i, v.xxh3_128, xxh3_128) + } +} + +@(test) +test_xxhash_zero_streamed_random_updates :: proc(t: ^testing.T) { + many_zeroes := make([]u8, 16 * 1024 * 1024) + defer delete(many_zeroes) + + // Streamed + for i, v in ZERO_VECTORS { + b := many_zeroes[:i] + + xxh_32_state, xxh_32_err := xxhash.XXH32_create_state() + defer xxhash.XXH32_destroy_state(xxh_32_state) + testing.expect(t, xxh_32_err == nil, "Problem initializing XXH_32 state") + + xxh_64_state, xxh_64_err := xxhash.XXH64_create_state() + defer xxhash.XXH64_destroy_state(xxh_64_state) + testing.expect(t, xxh_64_err == nil, "Problem initializing XXH_64 state") + + xxh3_64_state, xxh3_64_err := xxhash.XXH3_create_state() + defer xxhash.XXH3_destroy_state(xxh3_64_state) + testing.expect(t, xxh3_64_err == nil, "Problem initializing XXH3_64 state") + + xxh3_128_state, xxh3_128_err := xxhash.XXH3_create_state() + defer xxhash.XXH3_destroy_state(xxh3_128_state) + testing.expect(t, xxh3_128_err == nil, "Problem initializing XXH3_128 state") + + // XXH3_128_update + random_seed := rand.create(t.seed) + for len(b) > 0 { + update_size := min(len(b), rand.int_max(8192, &random_seed)) + if update_size > 4096 { + update_size %= 73 + } + xxhash.XXH32_update (xxh_32_state, b[:update_size]) + xxhash.XXH64_update (xxh_64_state, b[:update_size]) + + xxhash.XXH3_64_update (xxh3_64_state, b[:update_size]) + xxhash.XXH3_128_update(xxh3_128_state, b[:update_size]) + + b = b[update_size:] + } + + // Now finalize + xxh32 := xxhash.XXH32_digest(xxh_32_state) + xxh64 := xxhash.XXH64_digest(xxh_64_state) + + xxh3_64 := xxhash.XXH3_64_digest(xxh3_64_state) + xxh3_128 := xxhash.XXH3_128_digest(xxh3_128_state) + + xxh32_error := fmt.tprintf("[ XXH32(%03d) ] Expected: %08x, got: %08x", i, v.xxh_32, xxh32) + xxh64_error := fmt.tprintf("[ XXH64(%03d) ] Expected: %16x, got: %16x", i, v.xxh_64, xxh64) + xxh3_64_error := fmt.tprintf("[XXH3_64(%03d) ] Expected: %16x, got: %16x", i, v.xxh3_64, xxh3_64) + xxh3_128_error := fmt.tprintf("[XXH3_128(%03d) ] Expected: %32x, got: %32x", i, v.xxh3_128, xxh3_128) + + testing.expect(t, xxh32 == v.xxh_32, xxh32_error) + testing.expect(t, xxh64 == v.xxh_64, xxh64_error) + testing.expect(t, xxh3_64 == v.xxh3_64, xxh3_64_error) + testing.expect(t, xxh3_128 == v.xxh3_128, xxh3_128_error) + } +} + +@test +test_xxhash_seeded :: proc(t: ^testing.T) { + buf := make([]u8, 256) + defer delete(buf) + + for seed, table in XXHASH_TEST_VECTOR_SEEDED { + for v, i in table { + b := buf[:i] + + xxh32 := xxhash.XXH32(b, u32(seed)) + xxh64 := xxhash.XXH64(b, seed) + xxh3_64 := xxhash.XXH3_64(b, seed) + xxh3_128 := xxhash.XXH3_128(b, seed) + + testing.expectf(t, xxh32 == v.xxh_32, "[ XXH32(%03d) ] Expected: %08x, got: %08x", i, v.xxh_32, xxh32) + testing.expectf(t, xxh64 == v.xxh_64, "[ XXH64(%03d) ] Expected: %16x, got: %16x", i, v.xxh_64, xxh64) + testing.expectf(t, xxh3_64 == v.xxh3_64, "[XXH3_64(%03d) ] Expected: %16x, got: %16x", i, v.xxh3_64, xxh3_64) + testing.expectf(t, xxh3_128 == v.xxh3_128, "[XXH3_128(%03d) ] Expected: %32x, got: %32x", i, v.xxh3_128, xxh3_128) + + if len(b) > xxhash.XXH3_MIDSIZE_MAX { + xxh3_state, _ := xxhash.XXH3_create_state() + xxhash.XXH3_64_reset_with_seed(xxh3_state, seed) + xxhash.XXH3_64_update(xxh3_state, b) + xxh3_64_streamed := xxhash.XXH3_64_digest(xxh3_state) + xxhash.XXH3_destroy_state(xxh3_state) + testing.expectf(t, xxh3_64_streamed == v.xxh3_64, "[XXH3_64s(%03d) ] Expected: %16x, got: %16x", i, v.xxh3_64, xxh3_64_streamed) + + xxh3_state2, _ := xxhash.XXH3_create_state() + xxhash.XXH3_128_reset_with_seed(xxh3_state2, seed) + xxhash.XXH3_128_update(xxh3_state2, b) + xxh3_128_streamed := xxhash.XXH3_128_digest(xxh3_state2) + xxhash.XXH3_destroy_state(xxh3_state2) + testing.expectf(t, xxh3_128_streamed == v.xxh3_128, "[XXH3_128s(%03d) ] Expected: %32x, got: %32x", i, v.xxh3_128, xxh3_128_streamed) + } } } - log :: proc(t: ^testing.T, v: any, loc := #caller_location) { - fmt.printf("[%v] ", loc) - fmt.printf("log: %v\n", v) +} + +@test +test_xxhash_secret :: proc(t: ^testing.T) { + buf := make([]u8, 256) + defer delete(buf) + + for secret, table in XXHASH_TEST_VECTOR_SECRET { + secret_bytes := transmute([]u8)secret + for v, i in table { + b := buf[:i] + + xxh3_128 := xxhash.XXH3_128(b, secret_bytes) + testing.expectf(t, xxh3_128 == v.xxh3_128_secret, "[XXH3_128(%03d)] Expected: %32x, got: %32x", i, v.xxh3_128_secret, xxh3_128) + } } } -main :: proc() { - t := testing.T{} - test_benchmark_runner(&t) - test_crc64_vectors(&t) - test_xxhash_vectors(&t) - test_xxhash_large(&t) +@test +test_crc64_vectors :: proc(t: ^testing.T) { + vectors := map[string][4]u64 { + "123456789" = { + 0x6c40df5f0b497347, // ECMA-182, + 0x995dc9bbdf1939fa, // XZ + 0x46a5a9388a5beffe, // ISO 3306 + 0xb90956c775a41001, // ISO 3306, input and output inverted + }, + "This is a test of the emergency broadcast system." = { + 0x344fe1d09c983d13, // ECMA-182 + 0x27db187fc15bbc72, // XZ + 0x187184d744afc49e, // ISO 3306 + 0xe7fcf1006b503b61, // ISO 3306, input and output inverted + }, + } + defer delete(vectors) - fmt.printf("%v/%v tests successful.\n", TEST_count - TEST_fail, TEST_count) - if TEST_fail > 0 { - os.exit(1) + for vector, expected in vectors { + b := transmute([]u8)vector + ecma := hash.crc64_ecma_182(b) + xz := hash.crc64_xz(b) + iso := hash.crc64_iso_3306(b) + iso2 := hash.crc64_iso_3306_inverse(b) + + testing.expectf(t, ecma == expected[0], "[ CRC-64 ECMA ] Expected: %016x, got: %016x", expected[0], ecma) + testing.expectf(t, xz == expected[1], "[ CRC-64 XZ ] Expected: %016x, got: %016x", expected[1], xz) + testing.expectf(t, iso == expected[2], "[ CRC-64 ISO 3306] Expected: %016x, got: %016x", expected[2], iso) + testing.expectf(t, iso2 == expected[3], "[~CRC-64 ISO 3306] Expected: %016x, got: %016x", expected[3], iso2) } } -/* - Benchmarks -*/ +@(test) +test_benchmark_xxh32 :: proc(t: ^testing.T) { + name := "XXH32 100 zero bytes" + options := &time.Benchmark_Options{ + rounds = 1_000, + bytes = 100, + setup = setup_xxhash, + bench = benchmark_xxh32, + teardown = teardown_xxhash, + } + err := time.benchmark(options, context.allocator) + testing.expectf(t, err == nil, "%s failed with err %v", name, err) + hash := u128(0x85f6413c) + testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash) + benchmark_print(name, options) +} + +@(test) +test_benchmark_xxh32_1MB :: proc(t: ^testing.T) { + name := "XXH32 1 MiB zero bytes" + options := &time.Benchmark_Options{ + rounds = 1_000, + bytes = 1_048_576, + setup = setup_xxhash, + bench = benchmark_xxh32, + teardown = teardown_xxhash, + } + err := time.benchmark(options, context.allocator) + testing.expectf(t, err == nil, "%s failed with err %v", name, err) + hash := u128(0x9430f97f) + testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash) + benchmark_print(name, options) +} + +@(test) +test_benchmark_xxh64 :: proc(t: ^testing.T) { + name := "XXH64 100 zero bytes" + options := &time.Benchmark_Options{ + rounds = 1_000, + bytes = 100, + setup = setup_xxhash, + bench = benchmark_xxh64, + teardown = teardown_xxhash, + } + err := time.benchmark(options, context.allocator) + testing.expectf(t, err == nil, "%s failed with err %v", name, err) + hash := u128(0x17bb1103c92c502f) + testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash) + benchmark_print(name, options) +} + +@(test) +test_benchmark_xxh64_1MB :: proc(t: ^testing.T) { + name := "XXH64 1 MiB zero bytes" + options := &time.Benchmark_Options{ + rounds = 1_000, + bytes = 1_048_576, + setup = setup_xxhash, + bench = benchmark_xxh64, + teardown = teardown_xxhash, + } + err := time.benchmark(options, context.allocator) + testing.expectf(t, err == nil, "%s failed with err %v", name, err) + hash := u128(0x87d2a1b6e1163ef1) + testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash) + benchmark_print(name, options) +} + +@(test) +test_benchmark_xxh3_64 :: proc(t: ^testing.T) { + name := "XXH3_64 100 zero bytes" + options := &time.Benchmark_Options{ + rounds = 1_000, + bytes = 100, + setup = setup_xxhash, + bench = benchmark_xxh3_64, + teardown = teardown_xxhash, + } + err := time.benchmark(options, context.allocator) + testing.expectf(t, err == nil, "%s failed with err %v", name, err) + hash := u128(0x801fedc74ccd608c) + testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash) + benchmark_print(name, options) +} + +@(test) +test_benchmark_xxh3_64_1MB :: proc(t: ^testing.T) { + name := "XXH3_64 1 MiB zero bytes" + options := &time.Benchmark_Options{ + rounds = 1_000, + bytes = 1_048_576, + setup = setup_xxhash, + bench = benchmark_xxh3_64, + teardown = teardown_xxhash, + } + err := time.benchmark(options, context.allocator) + testing.expectf(t, err == nil, "%s failed with err %v", name, err) + hash := u128(0x918780b90550bf34) + testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash) + benchmark_print(name, options) +} + +@(test) +test_benchmark_xxh3_128 :: proc(t: ^testing.T) { + name := "XXH3_128 100 zero bytes" + options := &time.Benchmark_Options{ + rounds = 1_000, + bytes = 100, + setup = setup_xxhash, + bench = benchmark_xxh3_128, + teardown = teardown_xxhash, + } + err := time.benchmark(options, context.allocator) + testing.expectf(t, err == nil, "%s failed with err %v", name, err) + hash := u128(0x6ba30a4e9dffe1ff801fedc74ccd608c) + testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash) + benchmark_print(name, options) +} + +@(test) +test_benchmark_xxh3_128_1MB :: proc(t: ^testing.T) { + name := "XXH3_128 1 MiB zero bytes" + options := &time.Benchmark_Options{ + rounds = 1_000, + bytes = 1_048_576, + setup = setup_xxhash, + bench = benchmark_xxh3_128, + teardown = teardown_xxhash, + } + err := time.benchmark(options, context.allocator) + testing.expectf(t, err == nil, "%s failed with err %v", name, err) + hash := u128(0xb6ef17a3448492b6918780b90550bf34) + testing.expectf(t, options.hash == hash, "%v hash expected to be %v, got %v", name, hash, options.hash) + benchmark_print(name, options) +} + +// Benchmarks setup_xxhash :: proc(options: ^time.Benchmark_Options, allocator := context.allocator) -> (err: time.Benchmark_Error) { assert(options != nil) @@ -113,289 +380,14 @@ benchmark_xxh3_128 :: proc(options: ^time.Benchmark_Options, allocator := contex return nil } -benchmark_print :: proc(name: string, options: ^time.Benchmark_Options) { - fmt.printf("\t[%v] %v rounds, %v bytes processed in %v ns\n\t\t%5.3f rounds/s, %5.3f MiB/s\n", +benchmark_print :: proc(name: string, options: ^time.Benchmark_Options, loc := #caller_location) { + log.infof("\n\t[%v] %v rounds, %v bytes processed in %v ns\n\t\t%5.3f rounds/s, %5.3f MiB/s", name, options.rounds, options.processed, time.duration_nanoseconds(options.duration), options.rounds_per_second, options.megabytes_per_second, + location=loc, ) -} - -@test -test_benchmark_runner :: proc(t: ^testing.T) { - fmt.println("Starting benchmarks:") - - name := "XXH32 100 zero bytes" - options := &time.Benchmark_Options{ - rounds = 1_000, - bytes = 100, - setup = setup_xxhash, - bench = benchmark_xxh32, - teardown = teardown_xxhash, - } - - err := time.benchmark(options, context.allocator) - expect(t, err == nil, name) - expect(t, options.hash == 0x85f6413c, name) - benchmark_print(name, options) - - name = "XXH32 1 MiB zero bytes" - options.bytes = 1_048_576 - err = time.benchmark(options, context.allocator) - expect(t, err == nil, name) - expect(t, options.hash == 0x9430f97f, name) - benchmark_print(name, options) - - name = "XXH64 100 zero bytes" - options.bytes = 100 - options.bench = benchmark_xxh64 - err = time.benchmark(options, context.allocator) - expect(t, err == nil, name) - expect(t, options.hash == 0x17bb1103c92c502f, name) - benchmark_print(name, options) - - name = "XXH64 1 MiB zero bytes" - options.bytes = 1_048_576 - err = time.benchmark(options, context.allocator) - expect(t, err == nil, name) - expect(t, options.hash == 0x87d2a1b6e1163ef1, name) - benchmark_print(name, options) - - name = "XXH3_64 100 zero bytes" - options.bytes = 100 - options.bench = benchmark_xxh3_64 - err = time.benchmark(options, context.allocator) - expect(t, err == nil, name) - expect(t, options.hash == 0x801fedc74ccd608c, name) - benchmark_print(name, options) - - name = "XXH3_64 1 MiB zero bytes" - options.bytes = 1_048_576 - err = time.benchmark(options, context.allocator) - expect(t, err == nil, name) - expect(t, options.hash == 0x918780b90550bf34, name) - benchmark_print(name, options) - - name = "XXH3_128 100 zero bytes" - options.bytes = 100 - options.bench = benchmark_xxh3_128 - err = time.benchmark(options, context.allocator) - expect(t, err == nil, name) - expect(t, options.hash == 0x6ba30a4e9dffe1ff801fedc74ccd608c, name) - benchmark_print(name, options) - - name = "XXH3_128 1 MiB zero bytes" - options.bytes = 1_048_576 - err = time.benchmark(options, context.allocator) - expect(t, err == nil, name) - expect(t, options.hash == 0xb6ef17a3448492b6918780b90550bf34, name) - benchmark_print(name, options) -} - -@test -test_xxhash_large :: proc(t: ^testing.T) { - many_zeroes := make([]u8, 16 * 1024 * 1024) - defer delete(many_zeroes) - - // All at once. - for i, v in ZERO_VECTORS { - b := many_zeroes[:i] - - fmt.printf("[test_xxhash_large] All at once. Size: %v\n", i) - - xxh32 := xxhash.XXH32(b) - xxh64 := xxhash.XXH64(b) - xxh3_64 := xxhash.XXH3_64(b) - xxh3_128 := xxhash.XXH3_128(b) - - xxh32_error := fmt.tprintf("[ XXH32(%03d) ] Expected: %08x. Got: %08x.", i, v.xxh_32, xxh32) - xxh64_error := fmt.tprintf("[ XXH64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh_64, xxh64) - xxh3_64_error := fmt.tprintf("[XXH3_64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh3_64, xxh3_64) - xxh3_128_error := fmt.tprintf("[XXH3_128(%03d) ] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128) - - expect(t, xxh32 == v.xxh_32, xxh32_error) - expect(t, xxh64 == v.xxh_64, xxh64_error) - expect(t, xxh3_64 == v.xxh3_64, xxh3_64_error) - expect(t, xxh3_128 == v.xxh3_128, xxh3_128_error) - } - - when #config(RAND_STATE, -1) >= 0 && #config(RAND_INC, -1) >= 0 { - random_seed := rand.Rand{ - state = u64(#config(RAND_STATE, -1)), - inc = u64(#config(RAND_INC, -1)), - } - fmt.printf("Using user-selected seed {{%v,%v}} for update size randomness.\n", random_seed.state, random_seed.inc) - } else { - random_seed := rand.create(u64(intrinsics.read_cycle_counter())) - fmt.printf("Randonly selected seed {{%v,%v}} for update size randomness.\n", random_seed.state, random_seed.inc) - } - - // Streamed - for i, v in ZERO_VECTORS { - b := many_zeroes[:i] - - fmt.printf("[test_xxhash_large] Streamed. Size: %v\n", i) - - // bytes_per_update := []int{1, 42, 13, 7, 16, 5, 23, 74, 1024, 511, 1023, 47} - // update_size_idx: int - - xxh_32_state, xxh_32_err := xxhash.XXH32_create_state() - defer xxhash.XXH32_destroy_state(xxh_32_state) - expect(t, xxh_32_err == nil, "Problem initializing XXH_32 state.") - - xxh_64_state, xxh_64_err := xxhash.XXH64_create_state() - defer xxhash.XXH64_destroy_state(xxh_64_state) - expect(t, xxh_64_err == nil, "Problem initializing XXH_64 state.") - - xxh3_64_state, xxh3_64_err := xxhash.XXH3_create_state() - defer xxhash.XXH3_destroy_state(xxh3_64_state) - expect(t, xxh3_64_err == nil, "Problem initializing XXH3_64 state.") - - xxh3_128_state, xxh3_128_err := xxhash.XXH3_create_state() - defer xxhash.XXH3_destroy_state(xxh3_128_state) - expect(t, xxh3_128_err == nil, "Problem initializing XXH3_128 state.") - - // XXH3_128_update - - for len(b) > 0 { - update_size := min(len(b), rand.int_max(8192, &random_seed)) - if update_size > 4096 { - update_size %= 73 - } - xxhash.XXH32_update (xxh_32_state, b[:update_size]) - xxhash.XXH64_update (xxh_64_state, b[:update_size]) - - xxhash.XXH3_64_update (xxh3_64_state, b[:update_size]) - xxhash.XXH3_128_update(xxh3_128_state, b[:update_size]) - - b = b[update_size:] - } - - // Now finalize - xxh32 := xxhash.XXH32_digest(xxh_32_state) - xxh64 := xxhash.XXH64_digest(xxh_64_state) - - xxh3_64 := xxhash.XXH3_64_digest(xxh3_64_state) - xxh3_128 := xxhash.XXH3_128_digest(xxh3_128_state) - - xxh32_error := fmt.tprintf("[ XXH32(%03d) ] Expected: %08x. Got: %08x.", i, v.xxh_32, xxh32) - xxh64_error := fmt.tprintf("[ XXH64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh_64, xxh64) - xxh3_64_error := fmt.tprintf("[XXH3_64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh3_64, xxh3_64) - xxh3_128_error := fmt.tprintf("[XXH3_128(%03d) ] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128) - - expect(t, xxh32 == v.xxh_32, xxh32_error) - expect(t, xxh64 == v.xxh_64, xxh64_error) - expect(t, xxh3_64 == v.xxh3_64, xxh3_64_error) - expect(t, xxh3_128 == v.xxh3_128, xxh3_128_error) - } -} - -@test -test_xxhash_vectors :: proc(t: ^testing.T) { - fmt.println("Verifying against XXHASH_TEST_VECTOR_SEEDED:") - - buf := make([]u8, 256) - defer delete(buf) - - for seed, table in XXHASH_TEST_VECTOR_SEEDED { - fmt.printf("\tSeed: %v\n", seed) - - for v, i in table { - b := buf[:i] - - xxh32 := xxhash.XXH32(b, u32(seed)) - xxh64 := xxhash.XXH64(b, seed) - xxh3_64 := xxhash.XXH3_64(b, seed) - xxh3_128 := xxhash.XXH3_128(b, seed) - - xxh32_error := fmt.tprintf("[ XXH32(%03d) ] Expected: %08x. Got: %08x.", i, v.xxh_32, xxh32) - xxh64_error := fmt.tprintf("[ XXH64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh_64, xxh64) - - xxh3_64_error := fmt.tprintf("[XXH3_64(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh3_64, xxh3_64) - xxh3_128_error := fmt.tprintf("[XXH3_128(%03d) ] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128) - - expect(t, xxh32 == v.xxh_32, xxh32_error) - expect(t, xxh64 == v.xxh_64, xxh64_error) - expect(t, xxh3_64 == v.xxh3_64, xxh3_64_error) - expect(t, xxh3_128 == v.xxh3_128, xxh3_128_error) - - if len(b) > xxhash.XXH3_MIDSIZE_MAX { - fmt.printf("XXH3 - size: %v\n", len(b)) - - xxh3_state, _ := xxhash.XXH3_create_state() - xxhash.XXH3_64_reset_with_seed(xxh3_state, seed) - xxhash.XXH3_64_update(xxh3_state, b) - xxh3_64_streamed := xxhash.XXH3_64_digest(xxh3_state) - xxhash.XXH3_destroy_state(xxh3_state) - xxh3_64s_error := fmt.tprintf("[XXH3_64s(%03d) ] Expected: %16x. Got: %16x.", i, v.xxh3_64, xxh3_64_streamed) - expect(t, xxh3_64_streamed == v.xxh3_64, xxh3_64s_error) - - xxh3_state2, _ := xxhash.XXH3_create_state() - xxhash.XXH3_128_reset_with_seed(xxh3_state2, seed) - xxhash.XXH3_128_update(xxh3_state2, b) - xxh3_128_streamed := xxhash.XXH3_128_digest(xxh3_state2) - xxhash.XXH3_destroy_state(xxh3_state2) - xxh3_128s_error := fmt.tprintf("[XXH3_128s(%03d) ] Expected: %32x. Got: %32x.", i, v.xxh3_128, xxh3_128_streamed) - expect(t, xxh3_128_streamed == v.xxh3_128, xxh3_128s_error) - } - } - } - - fmt.println("Verifying against XXHASH_TEST_VECTOR_SECRET:") - for secret, table in XXHASH_TEST_VECTOR_SECRET { - fmt.printf("\tSecret:\n\t\t\"%v\"\n", secret) - - secret_bytes := transmute([]u8)secret - - for v, i in table { - b := buf[:i] - - xxh3_128 := xxhash.XXH3_128(b, secret_bytes) - xxh3_128_error := fmt.tprintf("[XXH3_128(%03d)] Expected: %32x. Got: %32x.", i, v.xxh3_128_secret, xxh3_128) - - expect(t, xxh3_128 == v.xxh3_128_secret, xxh3_128_error) - } - } -} - -@test -test_crc64_vectors :: proc(t: ^testing.T) { - fmt.println("Verifying CRC-64:") - - vectors := map[string][4]u64 { - "123456789" = { - 0x6c40df5f0b497347, // ECMA-182, - 0x995dc9bbdf1939fa, // XZ - 0x46a5a9388a5beffe, // ISO 3306 - 0xb90956c775a41001, // ISO 3306, input and output inverted - }, - "This is a test of the emergency broadcast system." = { - 0x344fe1d09c983d13, // ECMA-182 - 0x27db187fc15bbc72, // XZ - 0x187184d744afc49e, // ISO 3306 - 0xe7fcf1006b503b61, // ISO 3306, input and output inverted - }, - } - - for vector, expected in vectors { - fmt.println("\tVector:", vector) - b := transmute([]u8)vector - ecma := hash.crc64_ecma_182(b) - xz := hash.crc64_xz(b) - iso := hash.crc64_iso_3306(b) - iso2 := hash.crc64_iso_3306_inverse(b) - - ecma_error := fmt.tprintf("[ CRC-64 ECMA ] Expected: %016x. Got: %016x.", expected[0], ecma) - xz_error := fmt.tprintf("[ CRC-64 XZ ] Expected: %016x. Got: %016x.", expected[1], xz) - iso_error := fmt.tprintf("[ CRC-64 ISO 3306] Expected: %016x. Got: %016x.", expected[2], iso) - iso2_error := fmt.tprintf("[~CRC-64 ISO 3306] Expected: %016x. Got: %016x.", expected[3], iso2) - - expect(t, ecma == expected[0], ecma_error) - expect(t, xz == expected[1], xz_error) - expect(t, iso == expected[2], iso_error) - expect(t, iso2 == expected[3], iso2_error) - } } \ No newline at end of file diff --git a/tests/core/hash/test_vectors_xxhash.odin b/tests/core/hash/test_vectors_xxhash.odin index 6a37aef30..f72e2699a 100644 --- a/tests/core/hash/test_vectors_xxhash.odin +++ b/tests/core/hash/test_vectors_xxhash.odin @@ -1,6 +1,4 @@ -/* - Hash Test Vectors -*/ +// Hash Test Vectors package test_core_hash XXHASH_Test_Vectors :: struct #packed { @@ -6789,4 +6787,4 @@ XXHASH_TEST_VECTOR_SECRET := map[string][257]XXHASH_Test_Vectors_With_Secret{ /* XXH3_128_with_secret */ 0x0f9b41191242ade48bbde48dff0d38ec, }, }, -} +} \ No newline at end of file