summaryrefslogtreecommitdiffstats
path: root/src/zstd/contrib/linux-kernel/test/XXHashUserlandTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/zstd/contrib/linux-kernel/test/XXHashUserlandTest.cpp166
1 files changed, 166 insertions, 0 deletions
diff --git a/src/zstd/contrib/linux-kernel/test/XXHashUserlandTest.cpp b/src/zstd/contrib/linux-kernel/test/XXHashUserlandTest.cpp
new file mode 100644
index 00000000..f50401a2
--- /dev/null
+++ b/src/zstd/contrib/linux-kernel/test/XXHashUserlandTest.cpp
@@ -0,0 +1,166 @@
+extern "C" {
+#include <linux/errno.h>
+#include <linux/xxhash.h>
+}
+#include <gtest/gtest.h>
+#include <array>
+#include <iostream>
+#include <memory>
+#include <string>
+#define XXH_STATIC_LINKING_ONLY
+#include <xxhash.h>
+
+using namespace std;
+
+namespace {
+const std::array<std::string, 11> kTestInputs = {
+ "",
+ "0",
+ "01234",
+ "0123456789abcde",
+ "0123456789abcdef",
+ "0123456789abcdef0",
+ "0123456789abcdef0123",
+ "0123456789abcdef0123456789abcde",
+ "0123456789abcdef0123456789abcdef",
+ "0123456789abcdef0123456789abcdef0",
+ "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
+};
+
+bool testXXH32(const void *input, const size_t length, uint32_t seed) {
+ return XXH32(input, length, seed) == xxh32(input, length, seed);
+}
+
+bool testXXH64(const void *input, const size_t length, uint32_t seed) {
+ return XXH64(input, length, seed) == xxh64(input, length, seed);
+}
+
+class XXH32State {
+ struct xxh32_state kernelState;
+ XXH32_state_t state;
+
+public:
+ explicit XXH32State(const uint32_t seed) { reset(seed); }
+ XXH32State(XXH32State const& other) noexcept {
+ xxh32_copy_state(&kernelState, &other.kernelState);
+ XXH32_copyState(&state, &other.state);
+ }
+ XXH32State& operator=(XXH32State const& other) noexcept {
+ xxh32_copy_state(&kernelState, &other.kernelState);
+ XXH32_copyState(&state, &other.state);
+ return *this;
+ }
+
+ void reset(const uint32_t seed) {
+ xxh32_reset(&kernelState, seed);
+ EXPECT_EQ(0, XXH32_reset(&state, seed));
+ }
+
+ void update(const void *input, const size_t length) {
+ EXPECT_EQ(0, xxh32_update(&kernelState, input, length));
+ EXPECT_EQ(0, (int)XXH32_update(&state, input, length));
+ }
+
+ bool testDigest() const {
+ return xxh32_digest(&kernelState) == XXH32_digest(&state);
+ }
+};
+
+class XXH64State {
+ struct xxh64_state kernelState;
+ XXH64_state_t state;
+
+public:
+ explicit XXH64State(const uint64_t seed) { reset(seed); }
+ XXH64State(XXH64State const& other) noexcept {
+ xxh64_copy_state(&kernelState, &other.kernelState);
+ XXH64_copyState(&state, &other.state);
+ }
+ XXH64State& operator=(XXH64State const& other) noexcept {
+ xxh64_copy_state(&kernelState, &other.kernelState);
+ XXH64_copyState(&state, &other.state);
+ return *this;
+ }
+
+ void reset(const uint64_t seed) {
+ xxh64_reset(&kernelState, seed);
+ EXPECT_EQ(0, XXH64_reset(&state, seed));
+ }
+
+ void update(const void *input, const size_t length) {
+ EXPECT_EQ(0, xxh64_update(&kernelState, input, length));
+ EXPECT_EQ(0, (int)XXH64_update(&state, input, length));
+ }
+
+ bool testDigest() const {
+ return xxh64_digest(&kernelState) == XXH64_digest(&state);
+ }
+};
+}
+
+TEST(Simple, Null) {
+ EXPECT_TRUE(testXXH32(NULL, 0, 0));
+ EXPECT_TRUE(testXXH64(NULL, 0, 0));
+}
+
+TEST(Stream, Null) {
+ struct xxh32_state state32;
+ xxh32_reset(&state32, 0);
+ EXPECT_EQ(-EINVAL, xxh32_update(&state32, NULL, 0));
+
+ struct xxh64_state state64;
+ xxh64_reset(&state64, 0);
+ EXPECT_EQ(-EINVAL, xxh64_update(&state64, NULL, 0));
+}
+
+TEST(Simple, TestInputs) {
+ for (uint32_t seed = 0; seed < 100000; seed = (seed + 1) * 3) {
+ for (auto const input : kTestInputs) {
+ EXPECT_TRUE(testXXH32(input.data(), input.size(), seed));
+ EXPECT_TRUE(testXXH64(input.data(), input.size(), (uint64_t)seed));
+ }
+ }
+}
+
+TEST(Stream, TestInputs) {
+ for (uint32_t seed = 0; seed < 100000; seed = (seed + 1) * 3) {
+ for (auto const input : kTestInputs) {
+ XXH32State s32(seed);
+ XXH64State s64(seed);
+ s32.update(input.data(), input.size());
+ s64.update(input.data(), input.size());
+ EXPECT_TRUE(s32.testDigest());
+ EXPECT_TRUE(s64.testDigest());
+ }
+ }
+}
+
+TEST(Stream, MultipleTestInputs) {
+ for (uint32_t seed = 0; seed < 100000; seed = (seed + 1) * 3) {
+ XXH32State s32(seed);
+ XXH64State s64(seed);
+ for (auto const input : kTestInputs) {
+ s32.update(input.data(), input.size());
+ s64.update(input.data(), input.size());
+ }
+ EXPECT_TRUE(s32.testDigest());
+ EXPECT_TRUE(s64.testDigest());
+ }
+}
+
+TEST(Stream, CopyState) {
+ for (uint32_t seed = 0; seed < 100000; seed = (seed + 1) * 3) {
+ XXH32State s32(seed);
+ XXH64State s64(seed);
+ for (auto const input : kTestInputs) {
+ auto t32(s32);
+ t32.update(input.data(), input.size());
+ s32 = t32;
+ auto t64(s64);
+ t64.update(input.data(), input.size());
+ s64 = t64;
+ }
+ EXPECT_TRUE(s32.testDigest());
+ EXPECT_TRUE(s64.testDigest());
+ }
+}