The generic binary search function bsearch() has no unit tests, while
the adjacent sort() function already has KUnit test coverage.
Add comprehensive KUnit tests covering:
- Empty arrays, single-element arrays
- First/middle/last element hits
- Keys outside the array range and in gaps between elements
- Duplicate elements and all-identical arrays
- Different element sizes (u8, int, u64)
- Descending-order arrays with reversed comparator
- Struct-based search where key type differs from element type
The tests exercise both the exported bsearch() and the inline
__inline_bsearch() implementation through the standard API.
Signed-off-by: Liu Zhuoran <liuho...@gmail.com>
---
lib/Kconfig.debug | 10 ++
lib/tests/Makefile | 1 +
lib/tests/bsearch_kunit.c | 275 ++++++++++++++++++++++++++++++++++++++
3 files changed, 286 insertions(+)
create mode 100644 lib/tests/bsearch_kunit.c
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 8ff5adcfe..67d600e86 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2348,6 +2348,16 @@ config TEST_SORT
If unsure, say N.
+config BSEARCH_KUNIT_TEST
+ tristate "Array-based bsearch test" if !KUNIT_ALL_TESTS
+ depends on KUNIT
+ default KUNIT_ALL_TESTS
+ help
+ This option enables the KUnit test for 'bsearch()' at boot,
+ or at module load time.
+
+ If unsure, say N.
+
config TEST_DIV64
tristate "64bit/32bit division and modulo test"
depends on DEBUG_KERNEL || m
diff --git a/lib/tests/Makefile b/lib/tests/Makefile
index 7e9c2fa52..4c8b758ef 100644
--- a/lib/tests/Makefile
+++ b/lib/tests/Makefile
@@ -5,6 +5,7 @@
# KUnit tests
CFLAGS_bitfield_kunit.o := $(DISABLE_STRUCTLEAK_PLUGIN)
obj-$(CONFIG_BASE64_KUNIT) += base64_kunit.o
+obj-$(CONFIG_BSEARCH_KUNIT_TEST) += bsearch_kunit.o
obj-$(CONFIG_BITOPS_KUNIT) += bitops_kunit.o
obj-$(CONFIG_BITFIELD_KUNIT) += bitfield_kunit.o
obj-$(CONFIG_BITS_TEST) += test_bits.o
diff --git a/lib/tests/bsearch_kunit.c b/lib/tests/bsearch_kunit.c
new file mode 100644
index 000000000..b3b1d5d98
--- /dev/null
+++ b/lib/tests/bsearch_kunit.c
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * KUnit tests for bsearch()
+ */
+
+#include <kunit/test.h>
+#include <linux/bsearch.h>
+#include <linux/module.h>
+
+static int cmp_int(const void *a, const void *b)
+{
+ return *(int *)a - *(int *)b;
+}
+
+static int cmp_int_desc(const void *a, const void *b)
+{
+ return *(int *)b - *(int *)a;
+}
+
+/* Empty array should return NULL */
+static void bsearch_test_empty(struct kunit *test)
+{
+ int arr[] = {1};
+ int key = 1;
+ void *result;
+
+ result = bsearch(&key, arr, 0, sizeof(int), cmp_int);
+ KUNIT_EXPECT_PTR_EQ(test, result, NULL);
+}
+
+/* Single element: found */
+static void bsearch_test_single_hit(struct kunit *test)
+{
+ int arr[] = {42};
+ int key = 42;
+ void *result;
+
+ result = bsearch(&key, arr, 1, sizeof(int), cmp_int);
+ KUNIT_EXPECT_NOT_NULL(test, result);
+ KUNIT_EXPECT_EQ(test, *(int *)result, 42);
+}
+
+/* Single element: not found */
+static void bsearch_test_single_miss(struct kunit *test)
+{
+ int arr[] = {42};
+ int key = 99;
+ void *result;
+
+ result = bsearch(&key, arr, 1, sizeof(int), cmp_int);
+ KUNIT_EXPECT_PTR_EQ(test, result, NULL);
+}
+
+/* Multi-element: key at beginning */
+static void bsearch_test_first_element(struct kunit *test)
+{
+ int arr[] = {10, 20, 30, 40, 50};
+ int key = 10;
+ void *result;
+
+ result = bsearch(&key, arr, 5, sizeof(int), cmp_int);
+ KUNIT_EXPECT_NOT_NULL(test, result);
+ KUNIT_EXPECT_EQ(test, *(int *)result, 10);
+}
+
+/* Multi-element: key at end */
+static void bsearch_test_last_element(struct kunit *test)
+{
+ int arr[] = {10, 20, 30, 40, 50};
+ int key = 50;
+ void *result;
+
+ result = bsearch(&key, arr, 5, sizeof(int), cmp_int);
+ KUNIT_EXPECT_NOT_NULL(test, result);
+ KUNIT_EXPECT_EQ(test, *(int *)result, 50);
+}
+
+/* Multi-element: key in the middle */
+static void bsearch_test_middle_element(struct kunit *test)
+{
+ int arr[] = {10, 20, 30, 40, 50};
+ int key = 30;
+ void *result;
+
+ result = bsearch(&key, arr, 5, sizeof(int), cmp_int);
+ KUNIT_EXPECT_NOT_NULL(test, result);
+ KUNIT_EXPECT_EQ(test, *(int *)result, 30);
+}
+
+/* Key smaller than all elements */
+static void bsearch_test_below_range(struct kunit *test)
+{
+ int arr[] = {10, 20, 30};
+ int key = 5;
+ void *result;
+
+ result = bsearch(&key, arr, 3, sizeof(int), cmp_int);
+ KUNIT_EXPECT_PTR_EQ(test, result, NULL);
+}
+
+/* Key larger than all elements */
+static void bsearch_test_above_range(struct kunit *test)
+{
+ int arr[] = {10, 20, 30};