On Thu, Mar 6, 2025 at 7:25 AM Petr Mladek pmladek@suse.com wrote:
On Fri 2025-02-21 15:34:30, Tamir Duberstein wrote:
Convert the printf() self-test to a KUnit test.
In the interest of keeping the patch reasonably-sized this doesn't refactor the tests into proper parameterized tests - it's all one big test case.
Signed-off-by: Tamir Duberstein tamird@gmail.com
Documentation/core-api/printk-formats.rst | 4 +- MAINTAINERS | 2 +- lib/Kconfig.debug | 12 +- lib/Makefile | 1 - lib/tests/Makefile | 1 + lib/{test_printf.c => tests/printf_kunit.c} | 188 +++++++++++++++------------- tools/testing/selftests/lib/config | 1 - tools/testing/selftests/lib/printf.sh | 4 - 8 files changed, 117 insertions(+), 96 deletions(-)
diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst index ecccc0473da9..4bdc394e86af 100644 --- a/Documentation/core-api/printk-formats.rst +++ b/Documentation/core-api/printk-formats.rst @@ -661,7 +661,7 @@ Do *not* use it from C. Thanks ======
-If you add other %p extensions, please extend <lib/test_printf.c> with -one or more test cases, if at all feasible. +If you add other %p extensions, please extend <lib/tests/printf_kunit.c> +with one or more test cases, if at all feasible.
Thank you for your cooperation and attention. diff --git a/MAINTAINERS b/MAINTAINERS index f076360ce3c6..b051ccf6b276 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -25510,8 +25510,8 @@ R: Sergey Senozhatsky senozhatsky@chromium.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux.git F: Documentation/core-api/printk-formats.rst -F: lib/test_printf.c F: lib/test_scanf.c +F: lib/tests/printf_kunit.c F: lib/vsprintf.c
VT1211 HARDWARE MONITOR DRIVER diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 7ddbfdacf895..d2b15f633227 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -2436,6 +2436,15 @@ config ASYNC_RAID6_TEST config TEST_HEXDUMP tristate "Test functions located in the hexdump module at runtime"
+config PRINTF_KUNIT_TEST
tristate "KUnit test printf() family of functions at runtime" if !KUNIT_ALL_TESTS
depends on KUNIT
default KUNIT_ALL_TESTS
help
Enable this option to test the printf functions at runtime.
If unsure, say N.
config STRING_KUNIT_TEST tristate "KUnit test string functions at runtime" if !KUNIT_ALL_TESTS depends on KUNIT @@ -2449,9 +2458,6 @@ config STRING_HELPERS_KUNIT_TEST config TEST_KSTRTOX tristate "Test kstrto*() family of functions at runtime"
-config TEST_PRINTF
tristate "Test printf() family of functions at runtime"
config TEST_SCANF tristate "Test scanf() family of functions at runtime"
diff --git a/lib/Makefile b/lib/Makefile index 961aef91d493..f31e6a3100ba 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -77,7 +77,6 @@ obj-$(CONFIG_TEST_RHASHTABLE) += test_rhashtable.o obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_keys.o obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o obj-$(CONFIG_TEST_DYNAMIC_DEBUG) += test_dynamic_debug.o -obj-$(CONFIG_TEST_PRINTF) += test_printf.o obj-$(CONFIG_TEST_SCANF) += test_scanf.o
obj-$(CONFIG_TEST_BITMAP) += test_bitmap.o diff --git a/lib/tests/Makefile b/lib/tests/Makefile index 8961fbcff7a4..183c6a838a5d 100644 --- a/lib/tests/Makefile +++ b/lib/tests/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_LINEAR_RANGES_TEST) += test_linear_ranges.o obj-$(CONFIG_MEMCPY_KUNIT_TEST) += memcpy_kunit.o CFLAGS_overflow_kunit.o = $(call cc-disable-warning, tautological-constant-out-of-range-compare) obj-$(CONFIG_OVERFLOW_KUNIT_TEST) += overflow_kunit.o +obj-$(CONFIG_PRINTF_KUNIT_TEST) += printf_kunit.o obj-$(CONFIG_SIPHASH_KUNIT_TEST) += siphash_kunit.o obj-$(CONFIG_SLUB_KUNIT_TEST) += slub_kunit.o obj-$(CONFIG_TEST_SORT) += test_sort.o diff --git a/lib/test_printf.c b/lib/tests/printf_kunit.c similarity index 87% rename from lib/test_printf.c rename to lib/tests/printf_kunit.c index 59dbe4f9a4cb..287bbfb61148 100644 --- a/lib/test_printf.c +++ b/lib/tests/printf_kunit.c @@ -3,9 +3,7 @@
- Test cases for printf facility.
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <linux/init.h> +#include <kunit/test.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/printk.h> @@ -25,8 +23,6 @@
#include <linux/property.h>
-#include "../tools/testing/selftests/kselftest_module.h"
#define BUF_SIZE 256 #define PAD_SIZE 16 #define FILL_CHAR '$' @@ -37,12 +33,17 @@ block \ __diag_pop();
-KSTM_MODULE_GLOBALS(); +static unsigned int total_tests;
+static char *test_buffer; +static char *alloced_buffer;
+static struct kunit *kunittest;
-static char *test_buffer __initdata; -static char *alloced_buffer __initdata; +#define tc_fail(fmt, ...) \
KUNIT_FAIL(kunittest, fmt, ##__VA_ARGS__)
-static int __printf(4, 0) __init +static void __printf(4, 0) do_test(int bufsize, const char *expect, int elen, const char *fmt, va_list ap) { @@ -57,52 +58,50 @@ do_test(int bufsize, const char *expect, int elen, va_end(aq);
if (ret != elen) {
pr_warn("vsnprintf(buf, %d, \"%s\", ...) returned %d, expected %d\n",
tc_fail("vsnprintf(buf, %d, \"%s\", ...) returned %d, expected %d",
It looks a bit strange that the 1st patch replaces pr_warn() with tc_fail() which hides KUNIT_FAIL().
And the 2nd patch replaces tc_fail() with KUNIT_FAIL().
It looks like a non-necessary churn.
It would be better to avoid the temporary "tc_fail" and swith to KUNIT_FAIL() already in this patch.
I did not find any comment about this in the earier versions of the patchset.
Is it just a result of the evolution of the patchset or is there any motivation for this?
The motivation was to keep the width of the macro the same in this first patch for ease of review, particularly in the 7 instances where the invocation wraps to a second line. If you prefer I go straight to KUNIT_FAIL, I can make that change.
What was the motivation to remove the trailing '\n', please?
It actually makes a difference from the printk() POV. Messages without the trailing '\n' are _not_ flushed to the console until another message is added. The reason is that they might still be appended by pr_cont(). And printk() emits only complete lines to the console.
In general, messages should include the trailing '\n' unless the code wants to append something later or the trailing '\n' is added by another layer of the code. It does not seem to be this case.
bufsize, fmt, ret, elen);
return 1;
return; }
[...]
I noticed in my testing that the trailing \n didn't change the test output, but I didn't know the details you shared about the trailing \n. I'll restore them, unless we jump straight to the KUNIT macros per the discussion above.
@@ -842,13 +836,15 @@ test_pointer(void) fourcc_pointer(); }
-static void __init selftest(void) +static void printf_test(struct kunit *test) { alloced_buffer = kmalloc(BUF_SIZE + 2*PAD_SIZE, GFP_KERNEL); if (!alloced_buffer) return;
I would use here:
KUNIT_ASSERT_NOT_NULL(test, alloced_buffer);
And move the same change for the other kmalloc() location from the 2nd patch.
I didn't do that here because I was trying to keep this patch as small as possible, and I wrote that in the commit message.
As for using KUNIT_ASSERT_NOT_NULL here, that would have to change back to an error return in the 2nd patch because this code moves into `suite_init`, which is called with `struct kunit_suite` rather than `struct kunit_test`, and KUnit assertion macros do not work with the former (and for good reason, because failures in suite setup cannot be attributed to a particular test case).
So I'd prefer to leave this as is.
test_buffer = alloced_buffer + PAD_SIZE;
kunittest = test;
test_basic(); test_number(); test_string();
Otherwise, it looks good to me.
Best Regards, Petr
Thank you for the review!