lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<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

Powered by Openwall GNU/*/Linux Powered by OpenVZ