From 96d0fcfbd13679aae8a746b0bf9ae33412c1198b Mon Sep 17 00:00:00 2001 From: JCW Date: Fri, 8 Aug 2025 15:46:41 +0100 Subject: [PATCH] Add unit tests Signed-off-by: JCW --- include/xrpl/beast/hash/xxhasher.h | 9 ++++- src/test/beast/xxhasher_test.cpp | 58 ++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/include/xrpl/beast/hash/xxhasher.h b/include/xrpl/beast/hash/xxhasher.h index 9cd343f544..6bd1a88631 100644 --- a/include/xrpl/beast/hash/xxhasher.h +++ b/include/xrpl/beast/hash/xxhasher.h @@ -172,7 +172,14 @@ public: explicit operator result_type() noexcept { - return retrieveHash(); + auto result = retrieveHash(); + resetBuffers(); + if (state_) + { + XXH3_freeState(state_); + state_ = nullptr; + } + return result; } }; diff --git a/src/test/beast/xxhasher_test.cpp b/src/test/beast/xxhasher_test.cpp index 5508e66076..81df98254b 100644 --- a/src/test/beast/xxhasher_test.cpp +++ b/src/test/beast/xxhasher_test.cpp @@ -20,6 +20,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include "../../../include/xrpl/protocol/digest.h" + namespace beast { class XXHasher_test : public unit_test::suite @@ -182,6 +184,60 @@ public: 17285302196561698791ULL); } + void + testOperatorResultTypeDoesTheSameAsOtherHashers() + { + testcase("Operator result type does the same as other hashers"); + xxhasher hasher1; + ripple::sha256_hasher hasher2{}; + + std::string object{"Hello xxhash"}; + hasher1(object.data(), object.size()); + hasher2(object.data(), object.size()); + auto xxhashResult1 = static_cast(hasher1); + auto xxhashResult2 = static_cast(hasher1); + + auto sha256Result1 = static_cast(hasher2); + auto sha256Result2 = static_cast(hasher2); + + auto xxhashChanged = xxhashResult1 == xxhashResult2; + auto sha256Changed = sha256Result1 == sha256Result2; + BEAST_EXPECT(xxhashChanged == sha256Changed); + } + + void + testHasherStateStillValidAfterReset() + { + testcase("Hasher state still valid after reset"); + { + xxhasher hasher1; + + std::string object{"Hello xxhash"}; + hasher1(object.data(), object.size()); + auto xxhashResult1 = static_cast(hasher1); + hasher1(object.data(), object.size()); + auto xxhashResult2 = static_cast(hasher1); + + BEAST_EXPECT(xxhashResult1 == xxhashResult2); + } + { + xxhasher hasher1; + + std::string object; + for (int i = 0; i < 100; i++) + { + object += "Hello, xxHash!"; + } + + hasher1(object.data(), object.size()); + auto xxhashResult1 = static_cast(hasher1); + hasher1(object.data(), object.size()); + auto xxhashResult2 = static_cast(hasher1); + + BEAST_EXPECT(xxhashResult1 == xxhashResult2); + } + } + void run() override { @@ -194,6 +250,8 @@ public: testBigObjectWithSmallAndBigUpdatesWithSeed(); testBigObjectWithOneUpdateWithoutSeed(); testBigObjectWithOneUpdateWithSeed(); + testOperatorResultTypeDoesTheSameAsOtherHashers(); + testHasherStateStillValidAfterReset(); } };