summaryrefslogtreecommitdiffstats
path: root/lib/tests
diff options
context:
space:
mode:
authorRyota Sakamoto <sakamo.ryota@gmail.com>2025-12-21 13:35:16 +0000
committerAndrew Morton <akpm@linux-foundation.org>2026-01-26 19:07:10 -0800
commitd30aca3eeffc18452e5cc5c4e59f1a4da2bd2f12 (patch)
treec5d91e1c98178a7c89c165c726c3d0cfaab6ba5b /lib/tests
parent0e7fd23f9293cee3c7f341498a0011d09c491510 (diff)
downloadlinux-d30aca3eeffc18452e5cc5c4e59f1a4da2bd2f12.tar.gz
linux-d30aca3eeffc18452e5cc5c4e59f1a4da2bd2f12.zip
lib/tests: convert test_min_heap module to KUnit
Move lib/test_min_heap.c to lib/tests/min_heap_kunit.c and convert it to use KUnit. This change switches the ad-hoc test code to standard KUnit test cases. The test data remains the same, but the verification logic is updated to use KUNIT_EXPECT_* macros. Also remove CONFIG_TEST_MIN_HEAP from arch/*/configs/* because it is no longer used. The new CONFIG_MIN_HEAP_KUNIT_TEST will be automatically enabled by CONFIG_KUNIT_ALL_TESTS. The reasons for converting to KUnit are: 1. Standardization: Switching from ad-hoc printk-based reporting to the standard KTAP format makes it easier for CI systems to parse and report test results 2. Better Diagnostics: Using KUNIT_EXPECT_* macros automatically provides detailed diagnostics on failure. 3. Tooling Integration: It allows the test to be managed and executed using standard KUnit tools. Link: https://lkml.kernel.org/r/20251221133516.321846-1-sakamo.ryota@gmail.com Signed-off-by: Ryota Sakamoto <sakamo.ryota@gmail.com> Acked-by: Kuan-Wei Chiu <visitorckw@gmail.com> Cc: Alexander Gordeev <agordeev@linux.ibm.com> Cc: Christian Borntraeger <borntraeger@linux.ibm.com> Cc: David Gow <davidgow@google.com> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Heiko Carstens <hca@linux.ibm.com> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Sven Schnelle <svens@linux.ibm.com> Cc: Vasily Gorbik <gor@linux.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'lib/tests')
-rw-r--r--lib/tests/Makefile1
-rw-r--r--lib/tests/min_heap_kunit.c209
2 files changed, 210 insertions, 0 deletions
diff --git a/lib/tests/Makefile b/lib/tests/Makefile
index 9a20608f65f5..088b80d16383 100644
--- a/lib/tests/Makefile
+++ b/lib/tests/Makefile
@@ -33,6 +33,7 @@ CFLAGS_longest_symbol_kunit.o += $(call cc-disable-warning, missing-prototypes)
obj-$(CONFIG_LONGEST_SYM_KUNIT_TEST) += longest_symbol_kunit.o
obj-$(CONFIG_MEMCPY_KUNIT_TEST) += memcpy_kunit.o
+obj-$(CONFIG_MIN_HEAP_KUNIT_TEST) += min_heap_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
diff --git a/lib/tests/min_heap_kunit.c b/lib/tests/min_heap_kunit.c
new file mode 100644
index 000000000000..9c1122661698
--- /dev/null
+++ b/lib/tests/min_heap_kunit.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Test cases for the min max heap.
+ */
+
+#include <kunit/test.h>
+#include <linux/min_heap.h>
+#include <linux/module.h>
+#include <linux/random.h>
+
+struct min_heap_test_case {
+ const char *str;
+ bool min_heap;
+};
+
+static struct min_heap_test_case min_heap_cases[] = {
+ {
+ .str = "min",
+ .min_heap = true,
+ },
+ {
+ .str = "max",
+ .min_heap = false,
+ },
+};
+
+KUNIT_ARRAY_PARAM_DESC(min_heap, min_heap_cases, str);
+
+DEFINE_MIN_HEAP(int, min_heap_test);
+
+static bool less_than(const void *lhs, const void *rhs, void __always_unused *args)
+{
+ return *(int *)lhs < *(int *)rhs;
+}
+
+static bool greater_than(const void *lhs, const void *rhs, void __always_unused *args)
+{
+ return *(int *)lhs > *(int *)rhs;
+}
+
+static void pop_verify_heap(struct kunit *test,
+ bool min_heap,
+ struct min_heap_test *heap,
+ const struct min_heap_callbacks *funcs)
+{
+ int *values = heap->data;
+ int last;
+
+ last = values[0];
+ min_heap_pop_inline(heap, funcs, NULL);
+ while (heap->nr > 0) {
+ if (min_heap)
+ KUNIT_EXPECT_LE(test, last, values[0]);
+ else
+ KUNIT_EXPECT_GE(test, last, values[0]);
+ last = values[0];
+ min_heap_pop_inline(heap, funcs, NULL);
+ }
+}
+
+static void test_heapify_all(struct kunit *test)
+{
+ const struct min_heap_test_case *params = test->param_value;
+ int values[] = { 3, 1, 2, 4, 0x8000000, 0x7FFFFFF, 0,
+ -3, -1, -2, -4, 0x8000000, 0x7FFFFFF };
+ struct min_heap_test heap = {
+ .data = values,
+ .nr = ARRAY_SIZE(values),
+ .size = ARRAY_SIZE(values),
+ };
+ struct min_heap_callbacks funcs = {
+ .less = params->min_heap ? less_than : greater_than,
+ .swp = NULL,
+ };
+ int i;
+
+ /* Test with known set of values. */
+ min_heapify_all_inline(&heap, &funcs, NULL);
+ pop_verify_heap(test, params->min_heap, &heap, &funcs);
+
+ /* Test with randomly generated values. */
+ heap.nr = ARRAY_SIZE(values);
+ for (i = 0; i < heap.nr; i++)
+ values[i] = get_random_u32();
+
+ min_heapify_all_inline(&heap, &funcs, NULL);
+ pop_verify_heap(test, params->min_heap, &heap, &funcs);
+}
+
+static void test_heap_push(struct kunit *test)
+{
+ const struct min_heap_test_case *params = test->param_value;
+ const int data[] = { 3, 1, 2, 4, 0x80000000, 0x7FFFFFFF, 0,
+ -3, -1, -2, -4, 0x80000000, 0x7FFFFFFF };
+ int values[ARRAY_SIZE(data)];
+ struct min_heap_test heap = {
+ .data = values,
+ .nr = 0,
+ .size = ARRAY_SIZE(values),
+ };
+ struct min_heap_callbacks funcs = {
+ .less = params->min_heap ? less_than : greater_than,
+ .swp = NULL,
+ };
+ int i, temp;
+
+ /* Test with known set of values copied from data. */
+ for (i = 0; i < ARRAY_SIZE(data); i++)
+ min_heap_push_inline(&heap, &data[i], &funcs, NULL);
+
+ pop_verify_heap(test, params->min_heap, &heap, &funcs);
+
+ /* Test with randomly generated values. */
+ while (heap.nr < heap.size) {
+ temp = get_random_u32();
+ min_heap_push_inline(&heap, &temp, &funcs, NULL);
+ }
+ pop_verify_heap(test, params->min_heap, &heap, &funcs);
+}
+
+static void test_heap_pop_push(struct kunit *test)
+{
+ const struct min_heap_test_case *params = test->param_value;
+ const int data[] = { 3, 1, 2, 4, 0x80000000, 0x7FFFFFFF, 0,
+ -3, -1, -2, -4, 0x80000000, 0x7FFFFFFF };
+ int values[ARRAY_SIZE(data)];
+ struct min_heap_test heap = {
+ .data = values,
+ .nr = 0,
+ .size = ARRAY_SIZE(values),
+ };
+ struct min_heap_callbacks funcs = {
+ .less = params->min_heap ? less_than : greater_than,
+ .swp = NULL,
+ };
+ int i, temp;
+
+ /* Fill values with data to pop and replace. */
+ temp = params->min_heap ? 0x80000000 : 0x7FFFFFFF;
+ for (i = 0; i < ARRAY_SIZE(data); i++)
+ min_heap_push_inline(&heap, &temp, &funcs, NULL);
+
+ /* Test with known set of values copied from data. */
+ for (i = 0; i < ARRAY_SIZE(data); i++)
+ min_heap_pop_push_inline(&heap, &data[i], &funcs, NULL);
+
+ pop_verify_heap(test, params->min_heap, &heap, &funcs);
+
+ heap.nr = 0;
+ for (i = 0; i < ARRAY_SIZE(data); i++)
+ min_heap_push_inline(&heap, &temp, &funcs, NULL);
+
+ /* Test with randomly generated values. */
+ for (i = 0; i < ARRAY_SIZE(data); i++) {
+ temp = get_random_u32();
+ min_heap_pop_push_inline(&heap, &temp, &funcs, NULL);
+ }
+ pop_verify_heap(test, params->min_heap, &heap, &funcs);
+}
+
+static void test_heap_del(struct kunit *test)
+{
+ const struct min_heap_test_case *params = test->param_value;
+ int values[] = { 3, 1, 2, 4, 0x8000000, 0x7FFFFFF, 0,
+ -3, -1, -2, -4, 0x8000000, 0x7FFFFFF };
+ struct min_heap_test heap;
+
+ min_heap_init_inline(&heap, values, ARRAY_SIZE(values));
+ heap.nr = ARRAY_SIZE(values);
+ struct min_heap_callbacks funcs = {
+ .less = params->min_heap ? less_than : greater_than,
+ .swp = NULL,
+ };
+ int i;
+
+ /* Test with known set of values. */
+ min_heapify_all_inline(&heap, &funcs, NULL);
+ for (i = 0; i < ARRAY_SIZE(values) / 2; i++)
+ min_heap_del_inline(&heap, get_random_u32() % heap.nr, &funcs, NULL);
+ pop_verify_heap(test, params->min_heap, &heap, &funcs);
+
+ /* Test with randomly generated values. */
+ heap.nr = ARRAY_SIZE(values);
+ for (i = 0; i < heap.nr; i++)
+ values[i] = get_random_u32();
+ min_heapify_all_inline(&heap, &funcs, NULL);
+
+ for (i = 0; i < ARRAY_SIZE(values) / 2; i++)
+ min_heap_del_inline(&heap, get_random_u32() % heap.nr, &funcs, NULL);
+ pop_verify_heap(test, params->min_heap, &heap, &funcs);
+}
+
+static struct kunit_case min_heap_test_cases[] = {
+ KUNIT_CASE_PARAM(test_heapify_all, min_heap_gen_params),
+ KUNIT_CASE_PARAM(test_heap_push, min_heap_gen_params),
+ KUNIT_CASE_PARAM(test_heap_pop_push, min_heap_gen_params),
+ KUNIT_CASE_PARAM(test_heap_del, min_heap_gen_params),
+ {},
+};
+
+static struct kunit_suite min_heap_test_suite = {
+ .name = "min_heap",
+ .test_cases = min_heap_test_cases,
+};
+
+kunit_test_suite(min_heap_test_suite);
+
+MODULE_DESCRIPTION("Test cases for the min max heap");
+MODULE_LICENSE("GPL");