From nobody Fri Sep 25 06:46:14 2026 Received: from mail-ua2-f12.google.com (mail-ua2-f12.google.com [74.125.226.204]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7548644781C for ; Tue, 15 Sep 2026 19:36:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.226.204 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789501014; cv=none; b=hO/4YPuicHt0iChoW8drCPwJvyMSPiqR86okvrpqTu92/g3B0pOrCVsfSzEsPoxX0QI3d6OWDf86MamNhKMCrggVfZj+Zow2PCYAsxTZEN0xyiFVD1BYMeHkZmf9j4Wl49FM5W/JULX46E61lDCzfy6ZwU9dglIFCYRsU5NZQo4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789501014; c=relaxed/simple; bh=+iRmEeBjlr3/YDeOaNs/gKK7p0cdRpBI+YfHHlG1884=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=pBoP9k9IymEFBIQRKbvWek1d12kGykgcU+oX2yqwty/UDQHoCEDM0KlLpR0620LHSnEJQDT+smd/Y0+mUnikFtIF3SuBrYO5MtkvzkOMiNlRVKSeiXT/7Q1ElKfPdrn7RbFiWVOU5FgsRI+Z6RyvmVrYsrEipHWB0MwAsBc/zAc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=eHa74lOb; arc=none smtp.client-ip=74.125.226.204 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) header.d=gmail.com header.i=@gmail.com header.b="eHa74lOb" Received: by mail-ua2-f12.google.com with SMTP id a1e0cc1a2514c-97e7c8c0754so27316241.0 for ; Tue, 15 Sep 2026 12:36:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789501011; x=1790105811; darn=vger.kernel.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=8pR1KvLC6hY0Jo9rktWgyCwoo7PEpaTdDrv6JZT+Rlw=; b=eHa74lObtbnJQr+zgXq3wjQr7K3SDUjfng1Q50hMFSTTHE7TRxVtQ8TlWbDaP8+ls4 RPNqNZ38FpggkAcZRJ9CJbEHe6lEc4n2TPkeKDW2SabUlJbPyCT9IIPGh9hJZ+TU8I8A JY+K+7KXRNXn04vUAbSUoKafMNqw4vHdT4/LvSE/dM8tda07gkJpa1zE7cdSfC6SFf8m xZk043MYGXaA843Ro2a4fXQvk910mY1O6vTw3CZ5QGuogaux3YAvlZ0KFmkLuxEdzw5P MX7DpY/LzhGaYbeczZtIcN9SqobSg5VAzhq96uObmIJCtWf2YoaaiLZ8M6R5kQGoFkYu SGCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789501011; x=1790105811; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=8pR1KvLC6hY0Jo9rktWgyCwoo7PEpaTdDrv6JZT+Rlw=; b=UybhE62rVkxsWa/EGFrqW2WwnTtShaX3zAXxmcLCixdmTyeNmmiBzpJv1kGhIlB286 jcd2Mm4dzkD9Fn9W2K9u3EZKJLAuWUcJToZ4Vhv4PnfwJTT+G2/fZCMWq+7cbxM0xZCs 763l8zMqzMoQmLV2/BCjLylF+RKLiOtgTNalaL9zbzoWECuJlM/dIJHJpUp8tvMaDlgg HGaSEWBxPAo9PsoE8qHkvXyfk504jUiLrWz9InInwsRoXlCaZy0lrvW7naAArziShrEA 44oJ9UwLMbSUKDeXqXVc6wgvrS31hD9UrnXjNzgRCZ0tVpDx25X7NH2fmoNmShr9NnDz WIog== X-Forwarded-Encrypted: i=1; AKwUvBz9wYWXHDsGKaDsBFzRL7Ve4VEQgGmTt7Hu8Vs5QuX89101rdoIKK7DEA1KefopPOPsawf62XqNQPN8W9g=@vger.kernel.org X-Gm-Message-State: AFuF++nQasDtxCGVrDZjlmVc+rbQke7q0ntwHpkuX2pH6Pc5moYEEuq9 FOGSATVbeyGHQ0TvQbV6XhXz5OMvAIz4Ksd3bcSPh5Ek5vswQAWzl0Y= X-Gm-Gg: AYBFou1H5DKiieFTM9+bamNewU4ThMGmOcYvP5mP76TxbNH+Goktn+GbaGEU1wU/w51 ZnEtuufV2Oa1Rzue1yI6KcJqW7STkBoc2ra+vijinzdcc6xTfhqbtK3W/JH4za/C0IVIr2qxWfw Er13O6QH/4lHXx7fwaMOictsdjRubqcdwpHymVNT5iplZSqqlHEgw4vQcWCyrjS2nE80/puI1NW Pft/rZUXs+Fq1pOLTNW7WwhIn2rB0GQPJssU3n6lIIMFngpEWX0ahluGzkpicKXaI4cZcy4deKW OVJVZZiEeFZPWOK4tE4/vEDIx1xNqUW6JpzlizhZfi2TtnMWxJmlu1n7oXuVDyD11QEjD8TDaiW FX5UCeNCbxLRZw+qA2vm+e3btqffV+28xUko5jyxaQ2WoZI4Wd6Ys61GzgtRByOitSr8GeuZxg/ I6V6G+X2RtJs1dl6MnzMcy/NC1q35790oRmiyDcVDQe/Bia3ZGnmJ8S1OSDf77yFzYaKppkA6fM uZTxWD2DASALE75swuoSEmHyLu1rp5ORVLU8Yltu1ky6mXK+Q== X-Received: by 2002:a05:6102:32d2:b0:798:24e8:23f4 with SMTP id ada2fe7eead31-79d25ece59bmr2938976137.7.1789501011162; Tue, 15 Sep 2026 12:36:51 -0700 (PDT) Received: from localhost.localdomain ([186.158.238.108]) by smtp.gmail.com with ESMTPSA id ada2fe7eead31-79fb1148f57sm691450137.4.2026.09.15.12.36.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Sep 2026 12:36:50 -0700 (PDT) From: =?UTF-8?q?Nicol=C3=A1s=20Antinori?= To: Alice Ryhl , Burak Emir , Brendan Higgins , David Gow , Miguel Ojeda Cc: =?UTF-8?q?Nicol=C3=A1s=20Antinori?= , Alexandre Courbot , Andreas Hindborg , Benno Lossin , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Boqun Feng , Brigham Campbell , Daniel Almeida , Danilo Krummrich , Gary Guo , Jori Koolstra , =?UTF-8?q?Onur=20=C3=96zkan?= , Rae Moar , Shuah Khan , Tamir Duberstein , Trevor Gross , Yury Norov , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel-mentees@lists.linux.dev Subject: [PATCH RFC 1/3] rust: kunit: add #[should_panic] support Date: Tue, 15 Sep 2026 16:33:52 -0300 Message-ID: X-Mailer: git-send-email 2.47.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable KUnit tests in Rust are written using user-space like syntax. This patch adds support for the `#[should_panic]` attribute, enabling the user to test conditions that are expected to cause a panic and report the test as successful. Signed-off-by: Nicol=C3=A1s Antinori --- include/kunit/test.h | 1 + include/kunit/try-catch.h | 1 + lib/kunit/test.c | 14 ++++++++++++ lib/kunit/try-catch.c | 7 ++++++ rust/kernel/kunit.rs | 9 ++++++++ rust/kernel/lib.rs | 46 ++++++++++++++++++++++++++++++++++++--- rust/macros/kunit.rs | 21 ++++++++++++++++-- 7 files changed, 94 insertions(+), 5 deletions(-) diff --git a/include/kunit/test.h b/include/kunit/test.h index da5312e0dfa5..8b42f431e1c1 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -723,6 +723,7 @@ void __printf(2, 3) kunit_log_append(struct string_stre= am *log, const char *fmt, #define KUNIT_SUCCEED(test) _KUNIT_SAVE_LOC(test) void __noreturn __kunit_abort(struct kunit *test); +void __noreturn __kunit_abort_expecting_error(struct kunit *test); void __printf(6, 7) __kunit_do_failed_assertion(struct kunit *test, const struct kunit_loc *loc, diff --git a/include/kunit/try-catch.h b/include/kunit/try-catch.h index d4e1a5b98ed6..a47b1cfbcf93 100644 --- a/include/kunit/try-catch.h +++ b/include/kunit/try-catch.h @@ -54,6 +54,7 @@ struct kunit_try_catch { void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context); void __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch); +void __noreturn kunit_try_catch_throw_expecting_error(struct kunit_try_cat= ch *try_catch); static inline int kunit_try_catch_get_result(struct kunit_try_catch *try_c= atch) { diff --git a/lib/kunit/test.c b/lib/kunit/test.c index 09e3dabfac0c..32e5419a2d52 100644 --- a/lib/kunit/test.c +++ b/lib/kunit/test.c @@ -323,6 +323,20 @@ void __noreturn __kunit_abort(struct kunit *test) } EXPORT_SYMBOL_GPL(__kunit_abort); +void __noreturn __kunit_abort_expecting_error(struct kunit *test) +{ + kunit_try_catch_throw_expecting_error(&test->try_catch); /* Does not retu= rn. */ + + /* + * Throw could not abort from test. + * + * XXX: we should never reach this line! As kunit_try_catch_throw_expecti= ng_error + * is marked __noreturn. + */ + WARN_ONCE(true, "Throw could not abort from test!\n"); +} +EXPORT_SYMBOL_GPL(__kunit_abort_expecting_error); + void __kunit_do_failed_assertion(struct kunit *test, const struct kunit_loc *loc, enum kunit_assert_type type, diff --git a/lib/kunit/try-catch.c b/lib/kunit/try-catch.c index d84a879f0a78..123e1f86a5b3 100644 --- a/lib/kunit/try-catch.c +++ b/lib/kunit/try-catch.c @@ -22,6 +22,13 @@ void __noreturn kunit_try_catch_throw(struct kunit_try_c= atch *try_catch) } EXPORT_SYMBOL_GPL(kunit_try_catch_throw); +void __noreturn kunit_try_catch_throw_expecting_error(struct kunit_try_cat= ch *try_catch) +{ + try_catch->try_result =3D 0; + kthread_exit(0); +} +EXPORT_SYMBOL_GPL(kunit_try_catch_throw_expecting_error); + static int kunit_generic_run_threadfn_adapter(void *data) { struct kunit_try_catch *try_catch =3D data; diff --git a/rust/kernel/kunit.rs b/rust/kernel/kunit.rs index 91eaff8c186a..65a1040ee2b0 100644 --- a/rust/kernel/kunit.rs +++ b/rust/kernel/kunit.rs @@ -9,6 +9,9 @@ use crate::fmt; use crate::prelude::*; +#[doc(hidden)] +pub static KUNIT_SHOULD_PANIC: u32 =3D 0xDEAD7357; + /// Prints a KUnit error-level message. /// /// Public but hidden since it should only be used from KUnit generated co= de. @@ -345,6 +348,12 @@ fn rust_test_kunit_in_kunit_test() { assert!(in_kunit_test()); } + #[test] + #[should_panic] + fn rust_test_kunit_panic_in_kunit_test() { + panic!("This test should panic and pass"); + } + #[test] #[cfg(not(all()))] fn rust_test_kunit_always_disabled_test() { diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 4d5c96ddc49c..0f6c3c00ddd5 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -174,14 +174,54 @@ impl ModuleMetadata for LocalModule { }; } -#[cfg(not(testlib))] -#[panic_handler] -fn panic(info: &core::panic::PanicInfo<'_>) -> ! { +#[inline] +fn bug_on_panic(info: &core::panic::PanicInfo<'_>) -> ! { pr_emerg!("{}\n", info); // SAFETY: FFI call. unsafe { bindings::BUG() }; } +#[cfg(all(not(testlib), not(CONFIG_KUNIT)))] +#[panic_handler] +fn panic(info: &core::panic::PanicInfo<'_>) -> ! { + bug_on_panic(info); +} + +#[cfg(all(not(testlib), CONFIG_KUNIT))] +#[panic_handler] +fn panic(info: &core::panic::PanicInfo<'_>) -> ! { + // SAFETY: This function is safe to call even if CONFIG_KUNIT=3Dn. If = a null pointer is returned, + // the panic is handled same as if CONFIG_KUNIT=3Dn. + let kunit_test =3D unsafe { ::bindings::kunit_get_current_test() }; + if kunit_test.is_null() { + bug_on_panic(info); + } else { + // SAFETY: We are in the else branch of kunit_test.is_null() condi= tion, meaning that + // `::bindings::kunit_get_current_test()` returned a kunit struct = successfully. + let should_panic_ptr: *const u32 =3D unsafe { (*kunit_test).priv_ = as *const u32 }; + let should_panic_code: u32 =3D if should_panic_ptr.is_null() { + bug_on_panic(info); + } else { + // SAFETY: Already tested that the should_panic_ptr pointer is= not null, casting it to + // its value should be safe since kunit_test is not null and K= Unit Rust tests are + // initialized by assigning either null or a u32 value to the = priv_ field. + unsafe { *should_panic_ptr } + }; + + if should_panic_code =3D=3D crate::kunit::KUNIT_SHOULD_PANIC { + // SAFETY: We are in the else branch of kunit_test.is_null() c= ondition, meaning that + // `::bindings::kunit_get_current_test()` returned a kunit str= uct successfully. + unsafe { + (*kunit_test).status =3D ::kernel::bindings::kunit_status_= KUNIT_SUCCESS; + bindings::__kunit_abort_expecting_error(kunit_test); + }; + } else { + pr_emerg!("Invalid KUnit priv_ code 0x{:x}\n", should_panic_co= de); + bug_on_panic(info); + } + } +} + /// Produces a pointer to an object from a pointer to one of its fields. /// /// If you encounter a type mismatch due to the [`Opaque`] type, then use = [`Opaque::cast_into`] or diff --git a/rust/macros/kunit.rs b/rust/macros/kunit.rs index ae20ed6768f1..2c6405cebc0a 100644 --- a/rust/macros/kunit.rs +++ b/rust/macros/kunit.rs @@ -106,6 +106,11 @@ pub(crate) fn kunit_tests(test_suite: Ident, mut modul= e: ItemMod) -> Result; Tue, 15 Sep 2026 19:36:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.226.204 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789501021; cv=none; b=p/hv4pLPbyFDINaA6YzcCZH3JdCZ8pgpNIYQC67sWiE5DHBxpStOj+zlNVZih6sDvZmaxzfQj0K/ZN1Dv9gL4KjBp3PIF8Be2n3GnNtGsHgv555+DJ+jrYVcIMiBzFn11vBn5utM/3uoFjdHZQ/Sle7rh+Aoqr8sYnNgeyIoES8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789501021; c=relaxed/simple; bh=24j+YAsmr+yo0vlk5j9pKXxuyHWMHhXkvtbL6pgYsME=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ggESit/jysmFdqPbsJRvpiygbcVkMqk42fuIJbgzp7KS43FrIIJydzYbNZsS3YI2cq/yOW52NpG3lXDHzjS6IPs3q6jA47tYj1gZ6AyZwSruVTBcTSNsFVTZn5Gd71GoomVotnzde0ACHbNNZFNpIArpUWdOVgHNhish35zb2N8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=NGTuht7n; arc=none smtp.client-ip=74.125.226.204 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) header.d=gmail.com header.i=@gmail.com header.b="NGTuht7n" Received: by mail-ua2-f12.google.com with SMTP id a1e0cc1a2514c-982db8d3b79so53726241.1 for ; Tue, 15 Sep 2026 12:36:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789501018; x=1790105818; darn=vger.kernel.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=LWo+a1PwIvdyKSwMXLqscBhiuoyZo6YO0MGeXgp2PlQ=; b=NGTuht7nzQlyq3G1b5BiPnEotYatPty4AzXlq/xQY/FhjW8tMCFXDRzQNCsfXJ7Hqf BV+LWZTYNvxMIiw3P37WK2MWcREzgpgSmGuBYv/TvMFkp+ExZQ2XcrEf4bllNZzou+mr Kj4cGBtl2RXbN54vFYutxmLpCnUewOOAe0f9OVwQgKxJ7blmRdeJRbtkBv0Ur6ZQ6Nxo bBLKCXAP7I7afZ4yl2KcLlrZ04VwdTCFFNfbMMVDqT6nOR4182ECn6n3LHuUH4cc1Cti TPj3ioRA8jKfr0eIapjDGqJFGGC8KbxUmY6l9agO3Gvxy7MdQtp4UCWRZpktEC1BNXSl Rapg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789501018; x=1790105818; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=LWo+a1PwIvdyKSwMXLqscBhiuoyZo6YO0MGeXgp2PlQ=; b=wUkn1/hYmVxP8gBcjdcfaDpJcDluaqgkGxix02sYTAjGM7mUwTuhowJjE92kJ1rNF/ XqVLPe9eWIk/gJVHdcbxJ27TWtS/1IP+Zqz3TrkHAVRFzjlpt9UZtZEP2Axmi/4ldFhL NZUI5fAJYrehN+zVrattmrzymwNyUGYjW91aFMqkyNGddaUbu2Ako7N5vVr8IY7EwAlC YgLpfJQeBFz4gPOp1oix6GRKDV8bVKhOb0LjLhX3gjapzG/i1/onVURvp+/lzD0ot/Ce Tro3tLXu3tDQeJZGWnglvsCQtsVjU3rv6LLtP77oP7ms0vA7nFQeAf918QWMPaFo6pde PmSQ== X-Forwarded-Encrypted: i=1; AKwUvBxKaCkK67e0hyfhsGTYlvn4EeoBV6xZ+Sb0iTwgGm8A/CSLuRfeBAuX8Kvo10lLPcFVdxnRNhe1tPd5H/w=@vger.kernel.org X-Gm-Message-State: AFuF++m7Hk5CSnQlb9K0NJEgipM/meZw4uJG8ue/bWy3D8EwtiSxnokI DI4W6FqVtvmBH1hse4euw3NCISnyvBlMPO05PD0VpyGa2wXmFZ03TdI= X-Gm-Gg: AYBFou13dj5lw0TxkKIkT0KwYjhPd6q27I4nb8LJ9SsXhb4KBeZET0Vy4emZGaLX8HE LEnfSFBVke/vgF7OgIVX+JgTcpqJHvbfStFciHf6rmtag/4ojKJDY35LngrULCjtLLjIcC6bGcc toi69fZAgYg0vWONOQRzbbAMiY0hIe5AsO9AVXhpuFJyGYRLOPu6pcAJgIxoYKiIhyrqMlzNvkp qdB6B0imgU2LTBvnC9PIocAz+jy36Uxx7rRWwGGWa/ccVZi3bkEQ/W5nLIIzH+VwM5yVnjgJ9Gh z+SZa1leNtT0Z+coDlzivrkyu8qR3ag/gfAH9YooXsvZDK1Ezn43YyH456cFtXUxugCracCEp3s 4r9wR4P8yTPHDxcjXVilezbnRb5D8QrZbE4Oy0jZ03U54rzSbz6txhHYx2lZU91ziWlngal78PG fsxsymdnjx6mXBmgq220pESBLdy8SNd40FTdL4EPPeLZqUTqyO9Biy8v0+LYpnu2S7MTxb53JpL 3bjSZfu7zt4VdksHkVfTFOPJ6dy3BwB+ZrRXC7Xdk/0eIZqQQ== X-Received: by 2002:a05:6102:3708:b0:79f:3c2b:2f6d with SMTP id ada2fe7eead31-79f3c2b30f0mr4964130137.3.1789501018508; Tue, 15 Sep 2026 12:36:58 -0700 (PDT) Received: from localhost.localdomain ([186.158.238.108]) by smtp.gmail.com with ESMTPSA id ada2fe7eead31-79fb1148f57sm691450137.4.2026.09.15.12.36.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Sep 2026 12:36:58 -0700 (PDT) From: =?UTF-8?q?Nicol=C3=A1s=20Antinori?= To: Alice Ryhl , Burak Emir , Brendan Higgins , David Gow , Miguel Ojeda Cc: =?UTF-8?q?Nicol=C3=A1s=20Antinori?= , Alexandre Courbot , Andreas Hindborg , Benno Lossin , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Boqun Feng , Brigham Campbell , Daniel Almeida , Danilo Krummrich , Gary Guo , Jori Koolstra , =?UTF-8?q?Onur=20=C3=96zkan?= , Rae Moar , Shuah Khan , Tamir Duberstein , Trevor Gross , Yury Norov , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel-mentees@lists.linux.dev Subject: [PATCH RFC 2/3] rust: kunit: allow same test name with different #[cfg(...)] Date: Tue, 15 Sep 2026 16:33:53 -0300 Message-ID: <47c9315829c60be605a528b74795219561cd889f.1789500084.git.nico.antinori.7@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sometimes it is necessary to test the same code paths under different configurations. The `#[cfg(...)]` macro can be used to check if specific configurations are enabled and run tests accordingly. Currently, defining multiple tests with the same name under different `#[cfg(...)]` attributes results in a compilation error. This patch removes that restriction, allowing identical test names across different configurations. Additionally, it appends the active configuration to the test name, ensuring the runner clearly indicates which test executed and which was skipped. Signed-off-by: Nicol=C3=A1s Antinori --- rust/kernel/kunit.rs | 15 ++++++++++++ rust/macros/kunit.rs | 57 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/rust/kernel/kunit.rs b/rust/kernel/kunit.rs index 65a1040ee2b0..613c8d2aea78 100644 --- a/rust/kernel/kunit.rs +++ b/rust/kernel/kunit.rs @@ -348,6 +348,21 @@ fn rust_test_kunit_in_kunit_test() { assert!(in_kunit_test()); } + // Both tests with cfg have the same name on purpose because we are im= plicitly testing that + // tests with the same name but different configs do not throw a compi= lation error + #[test] + #[cfg(CONFIG_RUST_KUNIT_SELFTEST =3D "y")] + fn rust_test_kunit_parse_cfg_in_kunit_test() { + assert!(in_kunit_test()); + } + + #[test] + #[cfg(CONFIG_RUST_KUNIT_SELFTEST =3D "n")] + fn rust_test_kunit_parse_cfg_in_kunit_test() { + // This test should never run because of the `cfg`. + assert!(false) + } + #[test] #[should_panic] fn rust_test_kunit_panic_in_kunit_test() { diff --git a/rust/macros/kunit.rs b/rust/macros/kunit.rs index 2c6405cebc0a..605d925cd8f0 100644 --- a/rust/macros/kunit.rs +++ b/rust/macros/kunit.rs @@ -6,14 +6,19 @@ use std::ffi::CString; -use proc_macro2::TokenStream; +use proc_macro2::{ + TokenStream, + TokenTree, // +}; use quote::{ format_ident, quote, ToTokens, // }; use syn::{ + parse::ParseStream, parse_quote, + Attribute, Error, Ident, Item, @@ -22,6 +27,46 @@ Result, // }; +fn get_cfg_string(attr: &Attribute) -> Result { + let mut result =3D String::from("_cfg"); + attr.parse_args_with(|input: ParseStream<'_>| { + while !input.is_empty() { + build_cfg_string(input.parse()?, &mut result)?; + } + Ok(result) + }) +} + +fn build_cfg_string(tt: TokenTree, result: &mut String) -> Result<()> { + match tt { + TokenTree::Ident(ident) =3D> { + result.push('_'); + result.push_str(&ident.to_string().to_lowercase()); + } + TokenTree::Punct(ref punct) =3D> match punct.as_char() { + '=3D' =3D> { + result.push_str("_equals"); + } + _ =3D> { + return Err(Error::new_spanned( + punct, + "only \"=3D\" is allowed to check configurations", + )) + } + }, + TokenTree::Literal(lit) =3D> { + result.push('_'); + result.push_str(&lit.to_string().trim_matches('"').to_string()= ); + } + TokenTree::Group(group) =3D> { + for group_tt in group.stream() { + build_cfg_string(group_tt, result)?; + } + } + } + Ok(()) +} + pub(crate) fn kunit_tests(test_suite: Ident, mut module: ItemMod) -> Resul= t { if test_suite.to_string().len() > 255 { return Err(Error::new_spanned( @@ -106,6 +151,12 @@ pub(crate) fn kunit_tests(test_suite: Ident, mut modul= e: ItemMod) -> Result>>()? + .join("__"); + let should_panic =3D f .attrs .iter() @@ -113,7 +164,7 @@ pub(crate) fn kunit_tests(test_suite: Ident, mut module= : ItemMod) -> Result; Tue, 15 Sep 2026 19:37:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.227.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789501029; cv=none; b=RLJh+DN/eWhFfxSVzQH0oLH8xnk6wOZgIcXK8ff4b9S5xR4INqKz1GOCveNaU8wvEvgx4YrfmIQWmBqWdOQ/Cs5K6kXducyS4nU/6K8837sI6ifTmVLGWeHSLXLKzNYvQAWblK8yB01YmcR9uXQ4L81tG00YNMKTJzQOCMUSKAw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789501029; c=relaxed/simple; bh=iQpFxkadxuZthWNzpNDmq94Hthwi+6Tsc7gHXxzEn3E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Tx9O8QbaALagfdfFmeNwfbr4SF6t1qHN37Y5IWVexZBYmIK2Jb9liC8/Djy7EdeIR1G1ra+qNC0iwTsLOoWa5ABla8CkaSLUMIAOo9B4o4EQYazBxkaGSAV2u7NMLGsf798t3Qil2s+IsvNKUdnt9odsJrbndIhhBgqjxDVom20= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=QEnjNWOj; arc=none smtp.client-ip=74.125.227.41 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) header.d=gmail.com header.i=@gmail.com header.b="QEnjNWOj" Received: by mail-vs2-f41.google.com with SMTP id ada2fe7eead31-78a7003f94fso33921137.2 for ; Tue, 15 Sep 2026 12:37:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789501026; x=1790105826; darn=vger.kernel.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=Fv2qyWJdbrcJvcqAwpcW93SKoGJg7N/Guzup2THPVL4=; b=QEnjNWOj6178noHTDnNBoB2Ol/RwIhbNowHaIau87hbSioWk0PULq+aicSI1czJmjI n6B8DdUd6UXI4tnHq1+9rBjpGiGlILED009hK36JEfJj1xDd/gLOXCX5cW/ze1nFEqPZ O5XlyxRh/s0JuJL/iIz0Zup7S5yabHeEIf7a//bnfTd2XdriH0zxFrpc7NVf1ekK7qxR EFJNO6psC2eZxBVReJ1me4WW+d9BiqAgxhoyOOQcVgYHzZv8aiCokAq1dtaqeXeNIr+x Hh0IMmvGye0864punvMZa8VaeebU+s5ccgn78opWl1lR9Z6dhiKDtCxMOhRlJDbYk9zP OA2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789501026; x=1790105826; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=Fv2qyWJdbrcJvcqAwpcW93SKoGJg7N/Guzup2THPVL4=; b=xP7WSl+2G4RkUU6tu9JA+1oxMtLjxbRD3kKmRlr3Sf0KIuOINgtc1Hi7R3ANNlEOVz +zxd/adCYfFs62px1bPoq9d5j7FwqBCxZcfXlmZzlcmkZy3N7MvThxqnnPuoMKxk6sje 0B0hibO5NJe04cX7MBMaVpOkVSiIxvQw40cBcZ248bSBI/2KQ0z78FdqXDi5cfTs7IS3 KiLjb5r9W9l3uClCXHix7EbS36UQGhQkYrWof5HWTstm6kGWwSeVMFmeKdPZreiUcsxv +VVSb9Co/nGv2MD2FWLlpIaVxbyO3f10Oa4d9tEE5fwOM+HWdIuljzaGHKznIj9CR0vs ERVg== X-Forwarded-Encrypted: i=1; AKwUvBw4IBxxwAPM8wEKFJYaUMDGa3LVVGDGqkXbeh4/kpYILJrrakdYC8/bpcTk2sNUf1V2wZ12HCkmESfroNI=@vger.kernel.org X-Gm-Message-State: AFuF++kr+DV/8sLhqCfYGuAbRRqHil5VBj6N1vvtv5U7z3VpMNYh6ilh RY3iQjMfNWyWjQVOlL3S8nV2W6ZAXKYQfmuSg8rLF+wLAzeqvRn9/8w= X-Gm-Gg: AYBFou18xLxTarC6YozJDN6TQM0rbZTsmiXN+e2P9WQWsZuSF3mch8wmv/GJZXPTea0 jWzxx83rGf2rqYhB0InK5e5TdhuaFmLpHI9/LADD5DEMASHkBKZrBkWd6plBFOyQEMd8viNVVB6 vn37PIRTE05s5ZXSdtsqtZxxJ+cBJiUsc+ZuHOXKhkb8Qh4AeVCslxJjISnWLV1ZijBkLtJhfS5 dGNLrRIlEz2Jq8WpwgR0fFmKNxpfz2KofM2hhlEiqHzzp5isyyFzJhInEDAnPqydTh/6rluZYSS uaFg3DXI4JCnCeuPZtx5tRVhPieBtATJrxjHoLFOuS/1hV+4LN7EEzaKYJUXFfBk+W/FykQhPR2 vwQGkNs3rtQsElMb3GHsCq2sHtmb3W+90ialE0rBD2slPgk6R3lr0v1Sk4ciACb2eCs2vTapAc+ OhT8d7GAdiykbESE+4flCrTrE7IQyRgkvxcTnx9i/ZqEbOvVwPG5xzACuX1cIdv8zMQp8MopwVA Jp+1kfG+yZx+BI57u0FsqjMrctPSLgnX/Ne5svfkCe2+Gy4Rw== X-Received: by 2002:a05:6102:5607:b0:790:c7bb:43fd with SMTP id ada2fe7eead31-79b5bf316f7mr12420909137.8.1789501025587; Tue, 15 Sep 2026 12:37:05 -0700 (PDT) Received: from localhost.localdomain ([186.158.238.108]) by smtp.gmail.com with ESMTPSA id ada2fe7eead31-79fb1148f57sm691450137.4.2026.09.15.12.36.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Sep 2026 12:37:05 -0700 (PDT) From: =?UTF-8?q?Nicol=C3=A1s=20Antinori?= To: Alice Ryhl , Burak Emir , Brendan Higgins , David Gow , Miguel Ojeda Cc: =?UTF-8?q?Nicol=C3=A1s=20Antinori?= , Alexandre Courbot , Andreas Hindborg , Benno Lossin , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Boqun Feng , Brigham Campbell , Daniel Almeida , Danilo Krummrich , Gary Guo , Jori Koolstra , =?UTF-8?q?Onur=20=C3=96zkan?= , Rae Moar , Shuah Khan , Tamir Duberstein , Trevor Gross , Yury Norov , linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel-mentees@lists.linux.dev Subject: [PATCH RFC 3/3] rust: bitmap: kunit: uncomment owned_bitmap_out_of_bounds panic case Date: Tue, 15 Sep 2026 16:33:54 -0300 Message-ID: <1a319df6587bfdcfa497fc964a9a6d21a8988e54.1789500084.git.nico.antinori.7@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Rust KUnit tests now support `#[should_panic]` attribute. Uncomment the test so it can be run when CONFIG_RUST_BITMAP_HARDENED=3Dy. Signed-off-by: Nicol=C3=A1s Antinori --- rust/kernel/bitmap.rs | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/rust/kernel/bitmap.rs b/rust/kernel/bitmap.rs index b27e0ec80d64..a9935b2be8c5 100644 --- a/rust/kernel/bitmap.rs +++ b/rust/kernel/bitmap.rs @@ -571,33 +571,29 @@ fn bitmap_set_clear_find() -> Result<(), AllocError> { Ok(()) } + #[cfg(not(CONFIG_RUST_BITMAP_HARDENED))] #[test] fn owned_bitmap_out_of_bounds() -> Result<(), AllocError> { - // TODO: Kunit #[test]s do not support `cfg` yet, - // so we add it here in the body. - #[cfg(not(CONFIG_RUST_BITMAP_HARDENED))] - { - let mut b =3D BitmapVec::new(128, GFP_KERNEL)?; - b.set_bit(2048); - b.set_bit_atomic(2048); - b.clear_bit(2048); - b.clear_bit_atomic(2048); - assert_eq!(None, b.next_bit(2048)); - assert_eq!(None, b.next_zero_bit(2048)); - assert_eq!(None, b.last_bit()); - } + let mut b =3D BitmapVec::new(128, GFP_KERNEL)?; + b.set_bit(2048); + b.set_bit_atomic(2048); + b.clear_bit(2048); + b.clear_bit_atomic(2048); + assert_eq!(None, b.next_bit(2048)); + assert_eq!(None, b.next_zero_bit(2048)); + assert_eq!(None, b.last_bit()); Ok(()) } - // TODO: uncomment once kunit supports [should_panic] and `cfg`. - // #[cfg(CONFIG_RUST_BITMAP_HARDENED)] - // #[test] - // #[should_panic] - // fn owned_bitmap_out_of_bounds() -> Result<(), AllocError> { - // let mut b =3D BitmapVec::new(128, GFP_KERNEL)?; - // - // b.set_bit(2048); - // } + #[cfg(CONFIG_RUST_BITMAP_HARDENED)] + #[test] + #[should_panic] + fn owned_bitmap_out_of_bounds() -> Result<(), AllocError> { + let mut b =3D BitmapVec::new(128, GFP_KERNEL)?; + + b.set_bit(2048); + Ok(()) + } #[test] fn bitmap_copy_and_extend() -> Result<(), AllocError> { -- 2.47.3