[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20260119105857.797498-3-costa.shul@redhat.com>
Date: Mon, 19 Jan 2026 12:58:57 +0200
From: Costa Shulyupin <costa.shul@...hat.com>
To: Steven Rostedt <rostedt@...dmis.org>,
Tomas Glozar <tglozar@...hat.com>,
Ian Rogers <irogers@...gle.com>,
Arnaldo Carvalho de Melo <acme@...hat.com>,
Namhyung Kim <namhyung@...nel.org>,
Alexandre Chartre <alexandre.chartre@...cle.com>,
Costa Shulyupin <costa.shul@...hat.com>,
Blake Jones <blakejones@...gle.com>,
Yuzhuo Jing <yuzhuo@...gle.com>,
Leo Yan <leo.yan@....com>,
linux-kernel@...r.kernel.org,
linux-trace-kernel@...r.kernel.org
Subject: [PATCH v2 2/2] tools/rtla: Add unit tests for utils.c
Add unit tests for utility functions in src/utils.c using the Check
testing framework. The tests verify parse_cpu_set(), strtoi(), and
parse_prio() functions.
Unit tests are built conditionally when libcheck is available.
Run tests with 'make unit-test'.
The test framework uses the Check library which provides process
isolation for each test, preventing failures in one test from
affecting others.
Signed-off-by: Costa Shulyupin <costa.shul@...hat.com>
---
v2: Address feedback from Tomas Glozar
- Split the patch.
- Extract separate target unit-test.
- use build system
- libcheck: document, add to tools/build dependency detection
---
tools/tracing/rtla/Build | 1 +
tools/tracing/rtla/Makefile | 5 +
tools/tracing/rtla/Makefile.config | 8 ++
tools/tracing/rtla/README.txt | 1 +
tools/tracing/rtla/tests/unit/Build | 2 +
tools/tracing/rtla/tests/unit/Makefile.unit | 17 +++
tools/tracing/rtla/tests/unit/unit_tests.c | 123 ++++++++++++++++++++
7 files changed, 157 insertions(+)
create mode 100644 tools/tracing/rtla/tests/unit/Build
create mode 100644 tools/tracing/rtla/tests/unit/Makefile.unit
create mode 100644 tools/tracing/rtla/tests/unit/unit_tests.c
diff --git a/tools/tracing/rtla/Build b/tools/tracing/rtla/Build
index 6c9d5b36a315..3ce2e0f567fd 100644
--- a/tools/tracing/rtla/Build
+++ b/tools/tracing/rtla/Build
@@ -1 +1,2 @@
rtla-y += src/
+unit_tests-y += tests/unit/
diff --git a/tools/tracing/rtla/Makefile b/tools/tracing/rtla/Makefile
index 2701256abaf3..45690ee14544 100644
--- a/tools/tracing/rtla/Makefile
+++ b/tools/tracing/rtla/Makefile
@@ -33,12 +33,14 @@ DOCSRC := ../../../Documentation/tools/rtla/
FEATURE_TESTS := libtraceevent
FEATURE_TESTS += libtracefs
FEATURE_TESTS += libcpupower
+FEATURE_TESTS += libcheck
FEATURE_TESTS += libbpf
FEATURE_TESTS += clang-bpf-co-re
FEATURE_TESTS += bpftool-skeletons
FEATURE_DISPLAY := libtraceevent
FEATURE_DISPLAY += libtracefs
FEATURE_DISPLAY += libcpupower
+FEATURE_DISPLAY += libcheck
FEATURE_DISPLAY += libbpf
FEATURE_DISPLAY += clang-bpf-co-re
FEATURE_DISPLAY += bpftool-skeletons
@@ -47,6 +49,7 @@ all: $(RTLA)
include $(srctree)/tools/build/Makefile.include
include Makefile.rtla
+include tests/unit/Makefile.unit
# check for dependencies only on required targets
NON_CONFIG_TARGETS := clean install tarball doc doc_clean doc_install
@@ -109,6 +112,8 @@ clean: doc_clean fixdep-clean
$(Q)rm -f rtla rtla-static fixdep FEATURE-DUMP rtla-*
$(Q)rm -rf feature
$(Q)rm -f src/timerlat.bpf.o src/timerlat.skel.h example/timerlat_bpf_action.o
+ $(Q)rm -f $(UNIT_TESTS)
+
check: $(RTLA) tests/bpf/bpf_action_map.o
RTLA=$(RTLA) BPFTOOL=$(SYSTEM_BPFTOOL) prove -o -f -v tests/
examples: example/timerlat_bpf_action.o
diff --git a/tools/tracing/rtla/Makefile.config b/tools/tracing/rtla/Makefile.config
index 07ff5e8f3006..0bdd258b76de 100644
--- a/tools/tracing/rtla/Makefile.config
+++ b/tools/tracing/rtla/Makefile.config
@@ -61,6 +61,14 @@ else
$(info Please install libcpupower-dev/kernel-tools-libs-devel)
endif
+$(call feature_check,libcheck)
+ifeq ($(feature-libcheck), 1)
+ $(call detected,CONFIG_LIBCHECK)
+else
+ $(info libcheck is missing, building without unit tests support.)
+ $(info Please install check-devel/check)
+endif
+
ifndef BUILD_BPF_SKEL
# BPF skeletons are used to implement improved sample collection, enable
# them by default.
diff --git a/tools/tracing/rtla/README.txt b/tools/tracing/rtla/README.txt
index 43e98311d10f..a9faee4dbb3a 100644
--- a/tools/tracing/rtla/README.txt
+++ b/tools/tracing/rtla/README.txt
@@ -12,6 +12,7 @@ RTLA depends on the following libraries and tools:
- libtracefs
- libtraceevent
- libcpupower (optional, for --deepest-idle-state)
+ - libcheck (optional, for unit tests)
For BPF sample collection support, the following extra dependencies are
required:
diff --git a/tools/tracing/rtla/tests/unit/Build b/tools/tracing/rtla/tests/unit/Build
new file mode 100644
index 000000000000..5f1e531ea8c9
--- /dev/null
+++ b/tools/tracing/rtla/tests/unit/Build
@@ -0,0 +1,2 @@
+unit_tests-y += unit_tests.o
+unit_tests-y +=../../src/utils.o
diff --git a/tools/tracing/rtla/tests/unit/Makefile.unit b/tools/tracing/rtla/tests/unit/Makefile.unit
new file mode 100644
index 000000000000..2088c9cc3571
--- /dev/null
+++ b/tools/tracing/rtla/tests/unit/Makefile.unit
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+UNIT_TESTS := $(OUTPUT)unit_tests
+UNIT_TESTS_IN := $(UNIT_TESTS)-in.o
+
+$(UNIT_TESTS): $(UNIT_TESTS_IN)
+ $(QUIET_LINK)$(CC) $(LDFLAGS) -o $@ $^ -lcheck
+
+$(UNIT_TESTS_IN):
+ make $(build)=unit_tests
+
+unit-tests: FORCE
+ $(Q)if [ "$(feature-libcheck)" = "1" ]; then \
+ $(MAKE) $(UNIT_TESTS) && $(UNIT_TESTS); \
+ else \
+ echo "libcheck is missing, skipping unit tests. Please install check-devel/check"; \
+ fi
diff --git a/tools/tracing/rtla/tests/unit/unit_tests.c b/tools/tracing/rtla/tests/unit/unit_tests.c
new file mode 100644
index 000000000000..aa53f8605e36
--- /dev/null
+++ b/tools/tracing/rtla/tests/unit/unit_tests.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#define _GNU_SOURCE
+#include <check.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sched.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include "../../src/utils.h"
+
+START_TEST(test_strtoi)
+{
+ int result;
+ char buf[64];
+
+ ck_assert_int_eq(strtoi("123", &result), 0);
+ ck_assert_int_eq(result, 123);
+ ck_assert_int_eq(strtoi(" -456", &result), 0);
+ ck_assert_int_eq(result, -456);
+
+ snprintf(buf, sizeof(buf), "%d", INT_MAX);
+ ck_assert_int_eq(strtoi(buf, &result), 0);
+ snprintf(buf, sizeof(buf), "%ld", (long)INT_MAX + 1);
+ ck_assert_int_eq(strtoi(buf, &result), -1);
+
+ ck_assert_int_eq(strtoi("", &result), -1);
+ ck_assert_int_eq(strtoi("123abc", &result), -1);
+ ck_assert_int_eq(strtoi("123 ", &result), -1);
+}
+END_TEST
+
+START_TEST(test_parse_cpu_set)
+{
+ cpu_set_t set;
+ int nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
+
+ ck_assert_int_eq(parse_cpu_set("0", &set), 0);
+ ck_assert(CPU_ISSET(0, &set));
+ ck_assert(!CPU_ISSET(1, &set));
+
+ if (nr_cpus > 2) {
+ ck_assert_int_eq(parse_cpu_set("0,2", &set), 0);
+ ck_assert(CPU_ISSET(0, &set));
+ ck_assert(CPU_ISSET(2, &set));
+ }
+
+ if (nr_cpus > 3) {
+ ck_assert_int_eq(parse_cpu_set("0-3", &set), 0);
+ ck_assert(CPU_ISSET(0, &set));
+ ck_assert(CPU_ISSET(1, &set));
+ ck_assert(CPU_ISSET(2, &set));
+ ck_assert(CPU_ISSET(3, &set));
+ }
+
+ if (nr_cpus > 5) {
+ ck_assert_int_eq(parse_cpu_set("1-3,5", &set), 0);
+ ck_assert(!CPU_ISSET(0, &set));
+ ck_assert(CPU_ISSET(1, &set));
+ ck_assert(CPU_ISSET(2, &set));
+ ck_assert(CPU_ISSET(3, &set));
+ ck_assert(!CPU_ISSET(4, &set));
+ ck_assert(CPU_ISSET(5, &set));
+ }
+
+ ck_assert_int_eq(parse_cpu_set("-1", &set), 1);
+ ck_assert_int_eq(parse_cpu_set("abc", &set), 1);
+ ck_assert_int_eq(parse_cpu_set("9999", &set), 1);
+}
+END_TEST
+
+START_TEST(test_parse_prio)
+{
+ struct sched_attr attr;
+
+ ck_assert_int_eq(parse_prio("f:50", &attr), 0);
+ ck_assert_uint_eq(attr.sched_policy, SCHED_FIFO);
+ ck_assert_uint_eq(attr.sched_priority, 50U);
+
+ ck_assert_int_eq(parse_prio("r:30", &attr), 0);
+ ck_assert_uint_eq(attr.sched_policy, SCHED_RR);
+
+ ck_assert_int_eq(parse_prio("o:0", &attr), 0);
+ ck_assert_uint_eq(attr.sched_policy, SCHED_OTHER);
+ ck_assert_int_eq(attr.sched_nice, 0);
+
+ ck_assert_int_eq(parse_prio("d:10ms:100ms", &attr), 0);
+ ck_assert_uint_eq(attr.sched_policy, 6U);
+
+ ck_assert_int_eq(parse_prio("f:999", &attr), -1);
+ ck_assert_int_eq(parse_prio("o:-20", &attr), -1);
+ ck_assert_int_eq(parse_prio("d:100ms:10ms", &attr), -1);
+ ck_assert_int_eq(parse_prio("x:50", &attr), -1);
+}
+END_TEST
+
+Suite *utils_suite(void)
+{
+ Suite *s = suite_create("utils");
+ TCase *tc = tcase_create("core");
+
+ tcase_add_test(tc, test_strtoi);
+ tcase_add_test(tc, test_parse_cpu_set);
+ tcase_add_test(tc, test_parse_prio);
+
+ suite_add_tcase(s, tc);
+ return s;
+}
+
+int main(void)
+{
+ int num_failed;
+ SRunner *sr;
+
+ sr = srunner_create(utils_suite());
+ srunner_run_all(sr, CK_NORMAL);
+ num_failed = srunner_ntests_failed(sr);
+
+ srunner_free(sr);
+
+ return (num_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
--
2.52.0
Powered by blists - more mailing lists