[PATCH v2 2/4] test: self: add talloc selftest
Sascha Hauer
s.hauer at pengutronix.de
Fri Nov 7 06:41:10 PST 2025
From: Ahmad Fatoum <a.fatoum at barebox.org>
This self test exercises the hierarchical properties of talloc.
Signed-off-by: Ahmad Fatoum <a.fatoum at barebox.org>
Link: https://lore.barebox.org/20251027075438.2480311-2-a.fatoum@barebox.org
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
test/self/Kconfig | 6 +++
test/self/Makefile | 1 +
test/self/talloc.c | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 160 insertions(+)
diff --git a/test/self/Kconfig b/test/self/Kconfig
index f46253afc034486833da5696e9df76294f2504d3..936b12072e60fc8d946ecd488af20eae8e8aa950 100644
--- a/test/self/Kconfig
+++ b/test/self/Kconfig
@@ -48,6 +48,7 @@ config SELFTEST_ENABLE_ALL
select SELFTEST_IDR
select SELFTEST_TLV
select SELFTEST_DM
+ select SELFTEST_TALLOC
help
Selects all self-tests compatible with current configuration
@@ -61,6 +62,11 @@ config SELFTEST_MALLOC
help
Tests barebox memory allocator
+config SELFTEST_TALLOC
+ bool "talloc() selftest"
+ help
+ Tests barebox talloc allocator
+
config SELFTEST_PRINTF
bool "printf selftest"
help
diff --git a/test/self/Makefile b/test/self/Makefile
index 124607b375d84a59a1e650eb2d39ac533e4a3ff1..0bd947928a50f1fb0620bb9cc8c2e0d7c846237f 100644
--- a/test/self/Makefile
+++ b/test/self/Makefile
@@ -3,6 +3,7 @@
obj-$(CONFIG_SELFTEST) += core.o
obj-$(CONFIG_SELFTEST_RANGE) += range.o
obj-$(CONFIG_SELFTEST_MALLOC) += malloc.o
+obj-$(CONFIG_SELFTEST_TALLOC) += talloc.o
obj-$(CONFIG_SELFTEST_PRINTF) += printf.o
CFLAGS_printf.o += -Wno-format-security -Wno-format
obj-$(CONFIG_SELFTEST_PROGRESS_NOTIFIER) += progress-notifier.o
diff --git a/test/self/talloc.c b/test/self/talloc.c
new file mode 100644
index 0000000000000000000000000000000000000000..1322269af498eef3b64cfe4226b82d39bbd853b8
--- /dev/null
+++ b/test/self/talloc.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#define pr_fmt(fmt) "talloc: " fmt
+
+#include <common.h>
+#include <stdlib.h>
+#include <bselftest.h>
+#include <talloc.h>
+#include <linux/sizes.h>
+#include <linux/bitops.h>
+
+BSELFTEST_GLOBALS();
+
+static bool __selftest_check(bool cond, const char *func, int line)
+{
+ total_tests ++;
+ if (cond)
+ return true;
+
+ pr_err("assertion failure at %s:%d\n", func, line);
+
+ failed_tests++;
+ return false;
+}
+#define selftest_check(cond) __selftest_check((cond), __func__, __LINE__)
+
+#define STRESS_ALLOCS 1024
+#define STRESS_ITERS 5000
+
+static void talloc_basic_tests(void)
+{
+ void *root, *a, *b, *c;
+ void *tmp;
+
+ root = talloc_size(NULL, 0);
+ selftest_check(root == ZERO_SIZE_PTR);
+
+ root = talloc_new(NULL);
+ if (!selftest_check(!ZERO_OR_NULL_PTR(root)))
+ return;
+
+ a = talloc_size(root, 128);
+ selftest_check(a);
+
+ selftest_check(talloc_parent(a) == root);
+
+ b = talloc_zero_size(root, 256);
+ selftest_check(b && memchr_inv(b, 0x00, 256) == NULL);
+
+ c = talloc_strdup(root, "barebox talloc test");
+ selftest_check(c);
+
+ tmp = talloc_realloc_size(talloc_parent(a), a, 512);
+ if (selftest_check(tmp))
+ a = tmp;
+
+ selftest_check(talloc_parent(a) == root);
+
+ selftest_check(talloc_total_blocks(root) == 4);
+
+ /* Free child and verify parent is intact */
+ talloc_free(a);
+ selftest_check(talloc_total_blocks(root) == 3);
+
+ talloc_free(b);
+ selftest_check(talloc_total_blocks(root) == 2);
+
+ talloc_free(c);
+ selftest_check(talloc_total_blocks(root) == 1);
+
+ talloc_free(root);
+}
+
+static void talloc_hierarchy_tests(void)
+{
+ void *root = talloc_new(NULL);
+ void *lvl1, *lvl2, *lvl3;
+
+ lvl1 = talloc_new(root);
+ lvl2 = talloc_new(lvl1);
+ lvl3 = talloc_size(lvl2, 64);
+
+ selftest_check(lvl1 && lvl2 && lvl3);
+
+ selftest_check(talloc_parent(lvl3) == lvl2);
+
+ talloc_free(lvl1); /* should free all children */
+ selftest_check(talloc_total_blocks(root) == 1);
+
+ talloc_free(root);
+}
+
+static void talloc_stress_tests(void)
+{
+ void *root = talloc_new(NULL);
+ void *ptrs[STRESS_ALLOCS];
+
+ memset(ptrs, 0, sizeof(ptrs));
+
+ for (int iter = 0; iter < STRESS_ITERS; iter++) {
+ int idx = prandom_u32_max(STRESS_ALLOCS);
+ if (ptrs[idx]) {
+ talloc_free(ptrs[idx]);
+ ptrs[idx] = NULL;
+ } else {
+ size_t sz = prandom_u32_max(4096) + 1;
+ ptrs[idx] = talloc_size(root, sz);
+ if (selftest_check(ptrs[idx]) &&
+ prandom_u32_max(8) == 0) {
+ /* Occasionally realloc to a different size */
+ size_t new_sz = prandom_u32_max(8192) + 1;
+ void *tmp = talloc_realloc_size(NULL,
+ ptrs[idx], new_sz);
+ if (selftest_check(tmp))
+ ptrs[idx] = tmp;
+ }
+ }
+ }
+
+ for (int i = 0; i < STRESS_ALLOCS; i++) {
+ if (ptrs[i])
+ talloc_free(ptrs[i]);
+ }
+ talloc_free(root);
+}
+
+static void talloc_corner_cases(void)
+{
+ void *root = talloc_new(NULL);
+ void *large;
+
+ talloc_free(NULL);
+
+ void *realloc_null = talloc_realloc_size(NULL, NULL, 128);
+ selftest_check(realloc_null);
+ talloc_free(realloc_null);
+
+ /* Large alloc test (may fail gracefully if memory-constrained) */
+ large = talloc_size(root, 1024 * 1024 * 10);
+ if (selftest_check(large))
+ talloc_free(large);
+
+ talloc_free(root);
+}
+
+static void test_talloc(void)
+{
+ talloc_basic_tests();
+ talloc_hierarchy_tests();
+ talloc_stress_tests();
+ talloc_corner_cases();
+}
+bselftest(core, test_talloc);
--
2.47.3
More information about the barebox
mailing list