[PATCH RFC 5/7] tracing: Add a test for ftrace_parse_event_string()

Thomas Weißschuh <[email protected]>
Newsgroups org.kernel.vger.linux-trace-kernel,org.kernel.vger.linux-kernel
Message-ID <20260813-tracing-cli-event-filter-v1-5-57c4e8029c86@linutronix.de>
The parsing logic is a bit complicated and about to become more so.

Add a unit test to avoid regressions.

Signed-off-by: Thomas Weißschuh <[email protected]>
---
 kernel/trace/Kconfig             |   8 ++++
 kernel/trace/Makefile            |   1 +
 kernel/trace/trace.h             |   4 ++
 kernel/trace/trace_events.c      |   5 +-
 kernel/trace/trace_events_test.c | 101 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 118 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 084f34dc6c9f..e5eb26780abf 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -151,6 +151,14 @@ config EVENT_TRACING
 	select GLOB
 	bool
 
+config EVENT_TRACING_TEST
+	tristate "Test for event tracing" if !KUNIT_ALL_TESTS
+	depends on EVENT_TRACING
+	depends on KUNIT
+	default KUNIT_ALL_TESTS
+	help
+	  KUnit test for the event tracing implementation.
+
 config CONTEXT_SWITCH_TRACER
 	bool
 
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index f934ff586bd4..7bef5a84ce47 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -96,6 +96,7 @@ obj-$(CONFIG_EVENT_TRACING) += blktrace.o
 endif
 obj-$(CONFIG_EVENT_TRACING) += trace_events.o
 obj-$(CONFIG_EVENT_TRACING) += trace_export.o
+obj-$(CONFIG_EVENT_TRACING_TEST) += trace_events_test.o
 obj-$(CONFIG_FTRACE_SYSCALLS) += trace_syscalls.o
 ifeq ($(CONFIG_PERF_EVENTS),y)
 obj-$(CONFIG_EVENT_TRACING) += trace_event_perf.o
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index c00e4741f815..6bf4f031efa8 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -2505,3 +2505,7 @@ static inline int rv_init_interface(void)
 	})
 
 #endif /* _LINUX_KERNEL_TRACE_H */
+
+#if IS_ENABLED(CONFIG_KUNIT)
+void ftrace_parse_event_string(char *buf, char **match, char **sub, char **event, char **mod);
+#endif
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 4ff3f9214894..098a5aee5ec7 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -23,6 +23,8 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 
+#include <kunit/visibility.h>
+
 #include <trace/events/sched.h>
 #include <trace/syscall.h>
 
@@ -1411,7 +1413,7 @@ static int __ftrace_set_clr_event(struct trace_array *tr, const char *match,
 	return ret;
 }
 
-static void
+VISIBLE_IF_KUNIT void
 ftrace_parse_event_string(char *buf, char **match, char **sub, char **event, char **mod)
 {
 	*event = NULL;
@@ -1453,6 +1455,7 @@ ftrace_parse_event_string(char *buf, char **match, char **sub, char **event, cha
 			*match = NULL;
 	}
 }
+EXPORT_SYMBOL_IF_KUNIT(ftrace_parse_event_string);
 
 int ftrace_set_clr_event(struct trace_array *tr, const char *_buf, int set)
 {
diff --git a/kernel/trace/trace_events_test.c b/kernel/trace/trace_events_test.c
new file mode 100644
index 000000000000..e090a699b8d5
--- /dev/null
+++ b/kernel/trace/trace_events_test.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/module.h>
+
+#include <kunit/test.h>
+
+#include "trace.h"
+
+struct parse_event_test_case {
+	const char *input;
+
+	const char *match, *sub, *event, *mod;
+};
+
+static const struct parse_event_test_case parse_event_test_cases[] = {
+	{
+		"",
+		.match	= "",
+	},
+	{
+		"*:event",
+		.event	= "event",
+	},
+	{
+		":event",
+		.event	= "event",
+	},
+	{
+		"sub:*",
+		.sub	= "sub",
+	},
+	{
+		"sub:",
+		.sub	= "sub",
+	},
+	{
+		"sub:event",
+		.sub	= "sub",
+		.event	= "event",
+	},
+	{
+		"match",
+		.match	= "match",
+	},
+	{
+		":mod:module",
+		.mod	= "module",
+	},
+	{
+		"sub:event:mod:module",
+		.sub	= "sub",
+		.event	= "event",
+		.mod	= "module",
+	},
+};
+
+static void parse_event_test_desc(const struct parse_event_test_case *params, char *desc)
+{
+	snprintf(desc, KUNIT_PARAM_DESC_SIZE, "'%s'", params->input);
+}
+
+KUNIT_ARRAY_PARAM(parse_event, parse_event_test_cases, parse_event_test_desc);
+
+#define EXPECT_NULL_OR_STR_EQ(test, left, right)		\
+({								\
+	if ((left) != NULL)					\
+		KUNIT_EXPECT_STREQ(test, (left), (right));	\
+	else							\
+		KUNIT_EXPECT_NULL(test, (right));		\
+})
+
+static void parse_event(struct kunit *test)
+{
+	const struct parse_event_test_case *params = test->param_value;
+	char *input, *match, *sub, *event, *mod;
+
+	input = kunit_kstrdup(test, params->input, GFP_KERNEL);
+	if (!input)
+		kunit_skip(test, "ENOMEM");
+
+	ftrace_parse_event_string(input, &match, &sub, &event, &mod);
+
+	EXPECT_NULL_OR_STR_EQ(test, match, params->match);
+	EXPECT_NULL_OR_STR_EQ(test, sub, params->sub);
+	EXPECT_NULL_OR_STR_EQ(test, event, params->event);
+	EXPECT_NULL_OR_STR_EQ(test, mod, params->mod);
+}
+
+static struct kunit_case trace_events_test_cases[] = {
+	KUNIT_CASE_PARAM(parse_event, parse_event_gen_params),
+	{}
+};
+
+static struct kunit_suite trace_events_test_suite = {
+	.name = "trace-events",
+	.test_cases = trace_events_test_cases,
+};
+kunit_test_suite(trace_events_test_suite);
+
+
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");

-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.