From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=209.85.128.177 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793973736; b=DfxQSvFDBJcUQ5bnmCFI+6YKedStYB3izt69Clr39TmG7NFF7cc7vxFBL6HyVXACvGcH 35N0dFV9PiqWkzYjowiV7PT041+VJZExRDaZ3ZgF7Pd4U3Ms7KTnDg9zC/9fLxfJhF+eX VY0W+bD6AHnip0vDzc9/UZ8cDRdWO/eOkABDo6keNBq7mZ+hlmqJj8KF1sxzEnZiA6VwY m57I76CWbnG7jtgTRN3ke8uGiP90s7b7e5NjyWM/HTpGEgMqlBz8rvTF2Ri7gfmIc4F1O xmd87yVJ5JhkDnFjyt+pIdZsMvI/2YNd1NZ+JuOYpP2XSASkdggptvIcOI4olsR4wZQ== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793973736; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Forwarded-Encrypted:X-Gm-Message-State:X-Gm-Gg:X-Received:Received: From:Date:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding: Message-Id:X-B4-Tracking:X-Change-ID:To:Cc:X-Mailer; bh=BV7SBAPBE1+ZyxEmQ1zLwKaZE5gOIoHWad6+8dfnrbs=; b=Wfk6GWNY+Q5ZhWsESMHTz71UoxyOJI6l8MkaBp5EfA3vXGeEaWIDkntmaP6mI1S+6JAx MCWKiRN27eGjwel2j4MUkeyhE41lY3CaPBVSmof9WiApNg+5jln7QdEqn2QnW9wrPS3if uADhIZLdjxCxqGYnN32JHVOe71yXOt9gC4cXPSXsicml82z7mWNmPp/f5fLLdU+goLQz6 qq5N+oYWRkxEQpgTDg/e3TgBzH7NrndQ0qSuhyjvC1ZxYgr6NIcGSf7uiKlZcQOaNWWQf Hcd7V3PsuTwX6LLcucEfnN6fWARGrK2VBZVs97sGqNO/T+Ci6Sgj6NOSorjQ5pFfl5g== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20260707 header.b=yqaoFYkr; arc=none smtp.remote-ip=209.85.128.177 Received: from mail-yw1-f177.google.com (mail-yw1-f177.google.com [209.85.128.177]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 86549606EEB4 for ; Fri, 6 Nov 2026 14:02:15 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 86549606EEB4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20260707 header.b=yqaoFYkr Received: by mail-yw1-f177.google.com with SMTP id 00721157ae682-8b0d126f631so5317097b3.2 for ; Fri, 06 Nov 2026 06:02:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20260707; t=1793973734; x=1794578534; darn=vger.kernel.org; h=cc:to:message-id:content-transfer-encoding:content-type :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=BV7SBAPBE1+ZyxEmQ1zLwKaZE5gOIoHWad6+8dfnrbs=; b=yqaoFYkr/EgsIZj9Dkvg194mVo9k+dft6NEiLyTxULUnD41jCy8l65UTXWCPrI+f3A 9aNKOs7U4BiOk7fiii2EOw7eQSf52ViyrCQXSxRQYNQsbkQIBHUCj61P4lGzsMq+6Wb6 sJUiLhfE3q5YRp0LAnXVYSeoK1NPsDTvjdGTZYe9jFwDihiOtU9juXDwdbVq8T3cf54F spzysnZrR9T+ikdIQosUB/LPT/9wBPcGyUo3+Fk2rN9BE4QXmqp9yuMeoL4TqW7HRobH /2ofdu+2l6UvslLJUbkzDSUP73sF61WrtsA9HOo7DvIcRJ3rhNjhe4VebTzHJMsaUgFu W8vQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793973734; x=1794578534; h=cc:to:message-id:content-transfer-encoding:content-type :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=BV7SBAPBE1+ZyxEmQ1zLwKaZE5gOIoHWad6+8dfnrbs=; b=LmVTLxpN9UPzgToAFax4KTqH456nkbQlZgz4pELf8FIirFJ1kVbvGmKaCu73uvXTbK 9uS1buEaOdb4kZCAszAZMDfTwdwydLCHzwfdBbv+igkYmcfWcIsmQmVh/jjTQsht5EDb Y2kS56IoptmjPCmo41F2sWx6e2qhswXyqFjDzu2z0nH538tmX2cSOxOAFFg9M+23G6v2 2pSRlklmIbMM3GOXTmx0vyoJGaniQQrMAwHbRFPqXY7n2JjKPEGV5gdjY4X9Fm2cF9Yb feOaYfh+wGciMVvWIMOYWAzhewogQ3ieiP+VOinbtFlr/Fwm8Xpc3NumFmo5l1RILADr Dfyw== X-Forwarded-Encrypted: i=1; AL+hErFFskG9x1/hSfJCY+04c7sfXuZBYEIqqxHqltVWdpnA8cFVKBoZIbxWCvr6SHEKJX4twAqGjetDiijuEGw=@vger.kernel.org X-Gm-Message-State: APuU4Z8fyorNldCdNQFj6V2tx8R69x07RIHYf5rqlPK/lTjgmx1HRHgK P+2OvMtdafh95QeE6DtD+yPumpTNSRyxfzTzCa08nXS7SEvhwDaWHcNZ X-Gm-Gg: AYBFou3nbdy4KCWwS7+wCH0AXSwGFG8efVjkBUIDW1sYhZ9Mp15sGtdrurfYIN2hhUX IqytlR3lwcE/VGcD8Spyt/EY6YAEeOR1i9oR/ZFI+aTaY+uyoY4mDRGx4+j5dIzVao6Imsgxfw6 vvYuBohKzIyChwgR1dx1Z1boLfQz77ebOlAg/XZowlJiWjfsSe/E55zyVwWNz8o/UED57CdzF7I Rhq0mjylY0KmoB+4DBP5FAmcC3NYPowN/s6h7FVmb9lk2/6feY0kmTc9TCsFKrxBsZUXkGbF9Dy omzH8IGYOpr7Kz63TaUPvNz5wXQoj19DPLR/Z7oH6Gou0Rz7CZ+aNfQvOcvYox68dz272WR45NA sPXexxM6CBtkoPORt09DUCuK5fMha8HuUxsmci+1/Wc9tZ8c61Bto/fGwTB4Sk3j70bn1f/stxD Ub1Vsqvr2ZCCD3NtQcax7zwzcZ/SX5qFSnW7sKQy6mdqOKfMlmtyeXWzm9Paw/v1mvmO5P4RDpI 33SygGvY3DEA0rCoi0pGG4tkOc+rnADx4xxPwcj1cf81lAOa3CCOOkpb2Wbh8MH5s2bIiNumLQO qRXDX/WT2ueL4pmrVjvnRaKufx1k3F/Bb4iiSJJwnxgijxeJ1a9bG6mZ3a+PBOIiIb9jL3tnBW+ 7aCNdlxkZ6I7nCQCognVB/KQqnaimcijwXrRFfS9ATyhV0ddU/bTcPg2FMOj6 X-Received: by 2002:a05:690c:e3ea:b0:8ab:a473:fde8 with SMTP id 00721157ae682-8b341aca2ffmr15038617b3.54.1793973734029; Fri, 06 Nov 2026 06:02:14 -0800 (PST) Received: from lab01.myowncloud.network ([2601:cb:4000:1c5:5396:7ba1:d08a:ebca]) by smtp.gmail.com with ESMTPSA id 00721157ae682-8b33f852e80sm19184507b3.32.2026.11.06.06.02.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 Nov 2026 06:02:13 -0800 (PST) From: Amit Patole Date: Fri, 06 Nov 2026 09:02:11 -0500 Subject: [PATCH] lib/tests: add KUnit tests for xxHash X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20261106-kunit-xxhash-v1-1-7b79cb6a8998@gmail.com> X-B4-Tracking: v=1; b=H4sIAOLd7WoC/yXMQQqDMBBA0avIrBsw0Sp4FeliOo7NKKSS0RIQ7 26qy7f4fwflKKzQFTtE/onKN2TYRwHkMXzYyJANrnSNtWVj5i3IalLyqN64J9ZE2NYVEuRkiTx Kunb967Zu74lp/T/gOE7tqwZocAAAAA== X-Change-ID: 20261106-kunit-xxhash-25a4cca743ac To: Andrew Morton Cc: Nick Terrell , David Sterba , Brendan Higgins , David Gow , Rae Moar , linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, linux-kernel@vger.kernel.org, Amit Patole X-Mailer: b4 0.15.2 lib/xxhash.c provides xxh32() and xxh64(), used by zstd (frame checksums and long-distance matching), btrfs and erofs, where the values end up on disk. The crypto self-tests cover xxh64() through the "xxhash64" shash, but nothing tests xxh32() or the library interface directly. Add a KUnit suite with known answers from the reference xxHash implementation. The input is generated the same way as in xxHash's own sanity check, so the lengths 1, 14 and 222 reproduce the values published there. It covers: - xxh32() with two seeds and xxh64() with three, for lengths around the 4, 8, 16 and 32 byte boundaries of the algorithms; - the xxh64 streaming interface, split into two updates at every possible point and fed one byte at a time, and repeated xxh64_digest() calls; - xxh64_update() rejecting a NULL input with -EINVAL; - input at every offset from 1 to 7 bytes, which must not change the result. An AI coding assistant (Claude Opus 5.5) was used to draft the tests, and the expected values were generated with the reference implementation (python-xxhash 3.7.0) after checking it against the published sanity values. The tests were run with "tools/testing/kunit/kunit.py run" on UML (146/146 pass), built with W=1 without warnings, and checked against off-by-one changes to the length checks in xxh32(), xxh64() and xxh64_update(), which the suite catches. Signed-off-by: Amit Patole --- Tested on UML with a kunitconfig of CONFIG_KUNIT=y and CONFIG_XXHASH_KUNIT_TEST=y: 146/146 pass. --- lib/Kconfig.debug | 14 +++ lib/tests/Makefile | 1 + lib/tests/xxhash_kunit.c | 260 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 275 insertions(+) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 2d22638ec13a..d88fab338d4b 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -3461,6 +3461,20 @@ config RATELIMIT_KUNIT_TEST If unsure, say N. +config XXHASH_KUNIT_TEST + tristate "KUnit test for xxHash" if !KUNIT_ALL_TESTS + depends on KUNIT + select XXHASH + default KUNIT_ALL_TESTS + help + This option enables the KUnit test suite for lib/xxhash.c, the + xxh32() and xxh64() hashes used by zstd, btrfs and erofs. The + tests check known answers from the reference xxHash + implementation, the xxh64 streaming interface and unaligned + input. + + If unsure, say N. + config UUID_KUNIT_TEST tristate "KUnit test for UUID" if !KUNIT_ALL_TESTS depends on KUNIT diff --git a/lib/tests/Makefile b/lib/tests/Makefile index df0537e1b91f..8828efce4412 100644 --- a/lib/tests/Makefile +++ b/lib/tests/Makefile @@ -58,5 +58,6 @@ obj-$(CONFIG_USERCOPY_KUNIT_TEST) += usercopy_kunit.o obj-$(CONFIG_UTIL_MACROS_KUNIT) += util_macros_kunit.o obj-$(CONFIG_RATELIMIT_KUNIT_TEST) += test_ratelimit.o obj-$(CONFIG_UUID_KUNIT_TEST) += uuid_kunit.o +obj-$(CONFIG_XXHASH_KUNIT_TEST) += xxhash_kunit.o obj-$(CONFIG_TEST_RUNTIME_MODULE) += module/ diff --git a/lib/tests/xxhash_kunit.c b/lib/tests/xxhash_kunit.c new file mode 100644 index 000000000000..5575c3ec9662 --- /dev/null +++ b/lib/tests/xxhash_kunit.c @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KUnit tests for the xxHash implementation in lib/xxhash.c + * + * The expected values come from the reference xxHash implementation. The + * input is generated the same way as in xxHash's own sanity check, so the + * entries for lengths 1, 14 and 222 match the values published there. + */ + +#include +#include +#include +#include + +#define XXH_TEST_LEN 222 + +static const u32 xxh_prime32 = 2654435761U; +static const u64 xxh_prime64 = 11400714785074694797ULL; + +struct xxh32_case { + unsigned int len; + u32 seed; + u32 hash; +}; + +struct xxh64_case { + unsigned int len; + u64 seed; + u64 hash; +}; + +static const struct xxh32_case xxh32_cases[] = { + { 0, 0x00000000, 0x02cc5d05 }, + { 1, 0x00000000, 0xcf65b03e }, + { 3, 0x00000000, 0xc23884f5 }, + { 4, 0x00000000, 0xa9de7ce9 }, + { 5, 0x00000000, 0xeb1734bb }, + { 8, 0x00000000, 0xa3f6f44b }, + { 14, 0x00000000, 0x1208e7e2 }, + { 15, 0x00000000, 0x6b859e14 }, + { 16, 0x00000000, 0x93ba3759 }, + { 17, 0x00000000, 0x89fdc23e }, + { 31, 0x00000000, 0x5f40e562 }, + { 32, 0x00000000, 0xd89829ec }, + { 33, 0x00000000, 0x31a427e5 }, + { 63, 0x00000000, 0xf1d48fdb }, + { 64, 0x00000000, 0x02e95dbb }, + { 65, 0x00000000, 0x16992b3d }, + { 100, 0x00000000, 0x96ad8143 }, + { 222, 0x00000000, 0x5bd11dbd }, + { 0, 0x9e3779b1, 0x36b78ae7 }, + { 1, 0x9e3779b1, 0xb4545aa4 }, + { 3, 0x9e3779b1, 0x1a269947 }, + { 4, 0x9e3779b1, 0x2baafe83 }, + { 5, 0x9e3779b1, 0x5874dab0 }, + { 8, 0x9e3779b1, 0xc2a8e239 }, + { 14, 0x9e3779b1, 0x6af1d1fe }, + { 15, 0x9e3779b1, 0xad53090d }, + { 16, 0x9e3779b1, 0xa94fc1e1 }, + { 17, 0x9e3779b1, 0xc9910739 }, + { 31, 0x9e3779b1, 0x5c0c3350 }, + { 32, 0x9e3779b1, 0xa5c44467 }, + { 33, 0x9e3779b1, 0x0de5b1f9 }, + { 63, 0x9e3779b1, 0x956b3d77 }, + { 64, 0x9e3779b1, 0xcf82f830 }, + { 65, 0x9e3779b1, 0x428eec5f }, + { 100, 0x9e3779b1, 0x83d48124 }, + { 222, 0x9e3779b1, 0x58803c5f }, +}; + +static const struct xxh64_case xxh64_cases[] = { + { 0, 0x0000000000000000ULL, 0xef46db3751d8e999ULL }, + { 1, 0x0000000000000000ULL, 0xe934a84adb052768ULL }, + { 3, 0x0000000000000000ULL, 0xff7e1959cb50794aULL }, + { 4, 0x0000000000000000ULL, 0x9136a0dca57457eeULL }, + { 5, 0x0000000000000000ULL, 0x9b046fb1397f09a5ULL }, + { 8, 0x0000000000000000ULL, 0xcdbcf538e71d1348ULL }, + { 14, 0x0000000000000000ULL, 0x8282dcc4994e35c8ULL }, + { 15, 0x0000000000000000ULL, 0x180719316d622d84ULL }, + { 16, 0x0000000000000000ULL, 0x98c90b57fdfcb55cULL }, + { 17, 0x0000000000000000ULL, 0x0d39a2d051a30c2cULL }, + { 31, 0x0000000000000000ULL, 0x299b39a290e6d783ULL }, + { 32, 0x0000000000000000ULL, 0x18b216492bb44b70ULL }, + { 33, 0x0000000000000000ULL, 0x55c8dc3e578f5b59ULL }, + { 63, 0x0000000000000000ULL, 0xa9efbe0fa0f3f4e7ULL }, + { 64, 0x0000000000000000ULL, 0xef558f8acac2b5cdULL }, + { 65, 0x0000000000000000ULL, 0xde0f20dc2631af7aULL }, + { 100, 0x0000000000000000ULL, 0x4bfe019cd91d9ea4ULL }, + { 222, 0x0000000000000000ULL, 0xb641ae8cb691c174ULL }, + { 0, 0x000000009e3779b1ULL, 0xac75fda2929b17efULL }, + { 1, 0x000000009e3779b1ULL, 0x5014607643a9b4c3ULL }, + { 3, 0x000000009e3779b1ULL, 0xaa8584e83660f7d1ULL }, + { 4, 0x000000009e3779b1ULL, 0xcaab286bd8e9fdb5ULL }, + { 5, 0x000000009e3779b1ULL, 0x2af5249930f984ecULL }, + { 8, 0x000000009e3779b1ULL, 0xfe0c047a5353cdacULL }, + { 14, 0x000000009e3779b1ULL, 0xc3bd6bf63deb6df0ULL }, + { 15, 0x000000009e3779b1ULL, 0xd61105c20e91f99fULL }, + { 16, 0x000000009e3779b1ULL, 0xc900ad2d536b607eULL }, + { 17, 0x000000009e3779b1ULL, 0x495cd68a647c7a22ULL }, + { 31, 0x000000009e3779b1ULL, 0xda673d5feb5c1d79ULL }, + { 32, 0x000000009e3779b1ULL, 0xb3f33bdf93ade409ULL }, + { 33, 0x000000009e3779b1ULL, 0xe92c292f64bc3071ULL }, + { 63, 0x000000009e3779b1ULL, 0x6c911fadb05b6fc2ULL }, + { 64, 0x000000009e3779b1ULL, 0xb5eeba99264cc44fULL }, + { 65, 0x000000009e3779b1ULL, 0xd3f6ff3941e310caULL }, + { 100, 0x000000009e3779b1ULL, 0x4853706dc9625caeULL }, + { 222, 0x000000009e3779b1ULL, 0x20cb8ab7ae10c14aULL }, + { 0, 0x9e3779b97f4a7c15ULL, 0xc4349fc93c010000ULL }, + { 1, 0x9e3779b97f4a7c15ULL, 0x126bb57a12364aa5ULL }, + { 3, 0x9e3779b97f4a7c15ULL, 0xe23f055f9113033dULL }, + { 4, 0x9e3779b97f4a7c15ULL, 0xf6337e5fb526b92eULL }, + { 5, 0x9e3779b97f4a7c15ULL, 0x3fe27fb9d0eb8e4cULL }, + { 8, 0x9e3779b97f4a7c15ULL, 0x4fe88e05b3a5bfd8ULL }, + { 14, 0x9e3779b97f4a7c15ULL, 0xbdd0f167d252e0bbULL }, + { 15, 0x9e3779b97f4a7c15ULL, 0xb0298e00622d8613ULL }, + { 16, 0x9e3779b97f4a7c15ULL, 0xb37a43269a32566aULL }, + { 17, 0x9e3779b97f4a7c15ULL, 0xfd7e04ed256c9413ULL }, + { 31, 0x9e3779b97f4a7c15ULL, 0xb9fa34ecbf9b57ffULL }, + { 32, 0x9e3779b97f4a7c15ULL, 0xe65ea5f4eff5d5deULL }, + { 33, 0x9e3779b97f4a7c15ULL, 0xf166a3272cadc4abULL }, + { 63, 0x9e3779b97f4a7c15ULL, 0x0a36d884436efe01ULL }, + { 64, 0x9e3779b97f4a7c15ULL, 0xe7bd5052c0d2145eULL }, + { 65, 0x9e3779b97f4a7c15ULL, 0xfea9a8f0561339ddULL }, + { 100, 0x9e3779b97f4a7c15ULL, 0x8dd80a6ef6296bf7ULL }, + { 222, 0x9e3779b97f4a7c15ULL, 0x8cdf13ba7f241d67ULL }, +}; + +static u8 *xxh_test_buf(struct kunit *test) +{ + u64 gen = xxh_prime32; + u8 *buf; + int i; + + buf = kunit_kmalloc(test, XXH_TEST_LEN, GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, buf); + + for (i = 0; i < XXH_TEST_LEN; i++) { + buf[i] = gen >> 56; + gen *= xxh_prime64; + } + return buf; +} + +static void xxh32_case_desc(const struct xxh32_case *t, char *desc) +{ + snprintf(desc, KUNIT_PARAM_DESC_SIZE, "len %u seed %#x", + t->len, t->seed); +} + +static void xxh64_case_desc(const struct xxh64_case *t, char *desc) +{ + snprintf(desc, KUNIT_PARAM_DESC_SIZE, "len %u seed %#llx", + t->len, t->seed); +} + +KUNIT_ARRAY_PARAM(xxh32, xxh32_cases, xxh32_case_desc); +KUNIT_ARRAY_PARAM(xxh64, xxh64_cases, xxh64_case_desc); + +static void xxh32_test(struct kunit *test) +{ + const struct xxh32_case *t = test->param_value; + u8 *buf = xxh_test_buf(test); + + KUNIT_EXPECT_EQ(test, xxh32(buf, t->len, t->seed), t->hash); +} + +static void xxh64_test(struct kunit *test) +{ + const struct xxh64_case *t = test->param_value; + u8 *buf = xxh_test_buf(test); + + KUNIT_EXPECT_EQ(test, xxh64(buf, t->len, t->seed), t->hash); +} + +/* + * The streaming interface must give the same result as xxh64() however the + * input is split. Try every split into two updates, and one byte at a time. + */ +static void xxh64_streaming_test(struct kunit *test) +{ + const struct xxh64_case *t = test->param_value; + u8 *buf = xxh_test_buf(test); + struct xxh64_state state; + unsigned int split, i; + + for (split = 0; split <= t->len; split++) { + xxh64_reset(&state, t->seed); + KUNIT_ASSERT_EQ(test, xxh64_update(&state, buf, split), 0); + KUNIT_ASSERT_EQ(test, xxh64_update(&state, buf + split, + t->len - split), 0); + KUNIT_EXPECT_EQ_MSG(test, xxh64_digest(&state), t->hash, + "split at %u", split); + } + + xxh64_reset(&state, t->seed); + for (i = 0; i < t->len; i++) + KUNIT_ASSERT_EQ(test, xxh64_update(&state, buf + i, 1), 0); + KUNIT_EXPECT_EQ(test, xxh64_digest(&state), t->hash); + + /* xxh64_digest() does not change the state, so it can be repeated. */ + KUNIT_EXPECT_EQ(test, xxh64_digest(&state), t->hash); +} + +static void xxh64_update_null_test(struct kunit *test) +{ + struct xxh64_state state; + + xxh64_reset(&state, 0); + KUNIT_EXPECT_EQ(test, xxh64_update(&state, NULL, 0), -EINVAL); + /* A rejected update leaves the state as it was. */ + KUNIT_EXPECT_EQ(test, xxh64_digest(&state), xxh64(NULL, 0, 0)); +} + +/* The result does not depend on the alignment of the input. */ +static void xxh_unaligned_test(struct kunit *test) +{ + u8 *buf = xxh_test_buf(test); + u32 h32 = xxh32(buf, XXH_TEST_LEN, 0); + u64 h64 = xxh64(buf, XXH_TEST_LEN, 0); + u8 *copy; + int off; + + copy = kunit_kmalloc(test, XXH_TEST_LEN + 8, GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, copy); + + for (off = 1; off < 8; off++) { + struct xxh64_state state; + + memcpy(copy + off, buf, XXH_TEST_LEN); + KUNIT_EXPECT_EQ_MSG(test, xxh32(copy + off, XXH_TEST_LEN, 0), + h32, "offset %d", off); + KUNIT_EXPECT_EQ_MSG(test, xxh64(copy + off, XXH_TEST_LEN, 0), + h64, "offset %d", off); + + xxh64_reset(&state, 0); + xxh64_update(&state, copy + off, 5); + xxh64_update(&state, copy + off + 5, XXH_TEST_LEN - 5); + KUNIT_EXPECT_EQ_MSG(test, xxh64_digest(&state), h64, + "offset %d", off); + } +} + +static struct kunit_case xxhash_test_cases[] = { + KUNIT_CASE_PARAM(xxh32_test, xxh32_gen_params), + KUNIT_CASE_PARAM(xxh64_test, xxh64_gen_params), + KUNIT_CASE_PARAM(xxh64_streaming_test, xxh64_gen_params), + KUNIT_CASE(xxh64_update_null_test), + KUNIT_CASE(xxh_unaligned_test), + {} +}; + +static struct kunit_suite xxhash_test_suite = { + .name = "xxhash", + .test_cases = xxhash_test_cases, +}; + +kunit_test_suite(xxhash_test_suite); + +MODULE_DESCRIPTION("KUnit tests for xxHash"); +MODULE_LICENSE("GPL"); --- base-commit: 05441d697f7f9a927264f4058cbbc6a03dfcac9d change-id: 20261106-kunit-xxhash-25a4cca743ac Best regards, -- Amit Patole