diff options
| author | Ryota Sakamoto <sakamo.ryota@gmail.com> | 2025-12-21 13:35:16 +0000 |
|---|---|---|
| committer | Andrew Morton <akpm@linux-foundation.org> | 2026-01-26 19:07:10 -0800 |
| commit | d30aca3eeffc18452e5cc5c4e59f1a4da2bd2f12 (patch) | |
| tree | c5d91e1c98178a7c89c165c726c3d0cfaab6ba5b /lib/tests | |
| parent | 0e7fd23f9293cee3c7f341498a0011d09c491510 (diff) | |
| download | linux-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/Makefile | 1 | ||||
| -rw-r--r-- | lib/tests/min_heap_kunit.c | 209 |
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"); |
