From: Wen Yang <[email protected]>
Add CONFIG_TLOB_KUNIT_TEST (tristate, depends on RV_MON_TLOB && KUNIT,
default KUNIT_ALL_TESTS) with a test suite covering the uprobe-line
parser.
Tests call tlob_parse_uprobe_line() and tlob_parse_remove_line()
directly rather than going through the top-level write handler.
Mark both functions VISIBLE_IF_KUNIT and export with
EXPORT_SYMBOL_IF_KUNIT. Update the IS_ENABLED guard in tlob.h to use
CONFIG_TLOB_KUNIT_TEST instead of CONFIG_KUNIT.
Reviewed-by: Gabriele Monaco <[email protected]>
Signed-off-by: Wen Yang <[email protected]>
---
kernel/trace/rv/Makefile | 1 +
kernel/trace/rv/monitors/tlob/.kunitconfig | 5 +
kernel/trace/rv/monitors/tlob/Kconfig | 10 ++
kernel/trace/rv/monitors/tlob/tlob.c | 6 +-
kernel/trace/rv/monitors/tlob/tlob.h | 6 +
kernel/trace/rv/monitors/tlob/tlob_kunit.c | 139 +++++++++++++++++++++
6 files changed, 165 insertions(+), 2 deletions(-)
create mode 100644 kernel/trace/rv/monitors/tlob/.kunitconfig
create mode 100644 kernel/trace/rv/monitors/tlob/tlob_kunit.c
diff --git a/kernel/trace/rv/Makefile b/kernel/trace/rv/Makefile
index cd0ec11f0e05..92a04367ce93 100644
--- a/kernel/trace/rv/Makefile
+++ b/kernel/trace/rv/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_RV_MON_DEADLINE) += monitors/deadline/deadline.o
obj-$(CONFIG_RV_MON_NOMISS) += monitors/nomiss/nomiss.o
obj-$(CONFIG_RV_MON_WAKEUP) += monitors/wakeup/wakeup.o
obj-$(CONFIG_RV_MON_TLOB) += monitors/tlob/tlob.o
+obj-$(CONFIG_TLOB_KUNIT_TEST) += monitors/tlob/tlob_kunit.o
# Add new monitors here
obj-$(CONFIG_RV_UPROBE) += rv_uprobe.o
obj-$(CONFIG_RV_REACTORS) += rv_reactors.o
diff --git a/kernel/trace/rv/monitors/tlob/.kunitconfig b/kernel/trace/rv/monitors/tlob/.kunitconfig
new file mode 100644
index 000000000000..82a6f121016e
--- /dev/null
+++ b/kernel/trace/rv/monitors/tlob/.kunitconfig
@@ -0,0 +1,5 @@
+CONFIG_KUNIT=y
+CONFIG_UPROBES=y
+CONFIG_RV=y
+CONFIG_RV_MON_TLOB=y
+CONFIG_TLOB_KUNIT_TEST=y
diff --git a/kernel/trace/rv/monitors/tlob/Kconfig b/kernel/trace/rv/monitors/tlob/Kconfig
index aa43382073d2..f4fce35d38fb 100644
--- a/kernel/trace/rv/monitors/tlob/Kconfig
+++ b/kernel/trace/rv/monitors/tlob/Kconfig
@@ -10,3 +10,13 @@ config RV_MON_TLOB
monitor. tlob tracks per-task elapsed wall-clock time across a
user-delimited code section and emits error_env_tlob when the
elapsed time exceeds a configurable per-invocation budget.
+
+config TLOB_KUNIT_TEST
+ tristate "KUnit tests for tlob monitor" if !KUNIT_ALL_TESTS
+ depends on RV_MON_TLOB && KUNIT
+ default KUNIT_ALL_TESTS
+ help
+ Enable KUnit unit tests for the tlob RV monitor. The tests
+ cover the uprobe-line parser (tlob_parse_uprobe_line) and the
+ remove-line parser (tlob_parse_remove_line), verifying valid,
+ invalid, and out-of-range inputs without requiring a running kernel.
diff --git a/kernel/trace/rv/monitors/tlob/tlob.c b/kernel/trace/rv/monitors/tlob/tlob.c
index 99acd34726f1..e109390ba3ad 100644
--- a/kernel/trace/rv/monitors/tlob/tlob.c
+++ b/kernel/trace/rv/monitors/tlob/tlob.c
@@ -874,7 +874,7 @@ static ssize_t tlob_monitor_read(struct file *file,
* PATH may contain ':'; the last ':' separates path from offset.
* Returns 0, -EINVAL, or -ERANGE.
*/
-static int tlob_parse_uprobe_line(char *buf, u64 *thr_out,
+VISIBLE_IF_KUNIT int tlob_parse_uprobe_line(char *buf, u64 *thr_out,
char **path_out,
loff_t *start_out, loff_t *stop_out)
{
@@ -948,11 +948,12 @@ static int tlob_parse_uprobe_line(char *buf, u64 *thr_out,
*stop_out = (loff_t)stop_val;
return 0;
}
+EXPORT_SYMBOL_IF_KUNIT(tlob_parse_uprobe_line);
/*
* Parse "-PATH:OFFSET_START" (ftrace uprobe_events removal convention).
*/
-static int tlob_parse_remove_line(char *buf, char **path_out,
+VISIBLE_IF_KUNIT int tlob_parse_remove_line(char *buf, char **path_out,
loff_t *start_out)
{
char *binpath, *colon;
@@ -976,6 +977,7 @@ static int tlob_parse_remove_line(char *buf, char **path_out,
*start_out = (loff_t)off;
return 0;
}
+EXPORT_SYMBOL_IF_KUNIT(tlob_parse_remove_line);
static int tlob_create_or_delete_uprobe(char *buf)
{
diff --git a/kernel/trace/rv/monitors/tlob/tlob.h b/kernel/trace/rv/monitors/tlob/tlob.h
index 94e7382c2130..6ad9d5179ab6 100644
--- a/kernel/trace/rv/monitors/tlob/tlob.h
+++ b/kernel/trace/rv/monitors/tlob/tlob.h
@@ -146,4 +146,10 @@ static const struct automaton_tlob automaton_tlob = {
/* Upper budget bound (1 hour): keeps the u64 ns accumulators far from overflow. */
#define TLOB_MAX_THRESHOLD_NS 3600000000000ULL
+#if IS_ENABLED(CONFIG_TLOB_KUNIT_TEST)
+int tlob_parse_uprobe_line(char *buf, u64 *thr_out, char **path_out,
+ loff_t *start_out, loff_t *stop_out);
+int tlob_parse_remove_line(char *buf, char **path_out, loff_t *start_out);
+#endif /* CONFIG_TLOB_KUNIT_TEST */
+
#endif /* _RV_TLOB_H */
diff --git a/kernel/trace/rv/monitors/tlob/tlob_kunit.c b/kernel/trace/rv/monitors/tlob/tlob_kunit.c
new file mode 100644
index 000000000000..6a6fb57d0678
--- /dev/null
+++ b/kernel/trace/rv/monitors/tlob/tlob_kunit.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KUnit tests for the tlob RV monitor.
+ *
+ */
+#include <kunit/test.h>
+
+#include "tlob.h"
+
+MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
+
+/* Valid "p PATH:START STOP threshold=NS" lines. */
+static const char * const tlob_parse_valid[] = {
+ "p /usr/bin/myapp:4768 4848 threshold=5000000",
+ "p /usr/bin/myapp:0x12a0 0x12f0 threshold=10000000",
+ "p /opt/my:app/bin:0x100 0x200 threshold=1000000",
+};
+
+/* Malformed "p ..." lines that must be rejected with -EINVAL. */
+static const char * const tlob_parse_invalid[] = {
+ "p :0x100 0x200 threshold=5000",
+ "p /usr/bin/myapp:0x100 threshold=5000",
+ "p /usr/bin/myapp:-1 0x200 threshold=5000",
+ "p /usr/bin/myapp:0x100 -1 threshold=5000000", /* negative stop offset */
+ "p /usr/bin/myapp:0x100 0x200",
+ "p /usr/bin/myapp:0x100 0x100 threshold=5000",
+};
+
+/* threshold_ns < TLOB_MIN_THRESHOLD_NS or > TLOB_MAX_THRESHOLD_NS => -ERANGE. */
+static const char * const tlob_parse_out_of_range[] = {
+ "p /usr/bin/myapp:0x100 0x200 threshold=0",
+ "p /usr/bin/myapp:0x100 0x200 threshold=999",
+ "p /usr/bin/myapp:0x100 0x200 threshold=3600000000001",
+};
+
+/* Valid "-PATH:OFFSET_START" remove lines. */
+static const char * const tlob_remove_valid[] = {
+ "-/usr/bin/myapp:0x100",
+ "-/opt/my:app/bin:0x200",
+};
+
+/* Malformed remove lines that must be rejected with -EINVAL. */
+static const char * const tlob_remove_invalid[] = {
+ "-usr/bin/myapp:0x100",
+ "-/usr/bin/myapp",
+ "-/:0x100",
+ "-/usr/bin/myapp:-1", /* negative offset */
+ "-/usr/bin/myapp:abc",
+};
+
+static void tlob_parse_valid_accepted(struct kunit *test)
+{
+ u64 thr;
+ char *path;
+ loff_t start, stop;
+ char buf[128];
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(tlob_parse_valid); i++) {
+ strscpy(buf, tlob_parse_valid[i], sizeof(buf));
+ KUNIT_EXPECT_EQ(test, tlob_parse_uprobe_line(buf, &thr, &path,
+ &start, &stop), 0);
+ }
+}
+
+static void tlob_parse_invalid_rejected(struct kunit *test)
+{
+ u64 thr;
+ char *path;
+ loff_t start, stop;
+ char buf[128];
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(tlob_parse_invalid); i++) {
+ strscpy(buf, tlob_parse_invalid[i], sizeof(buf));
+ KUNIT_EXPECT_EQ(test, tlob_parse_uprobe_line(buf, &thr, &path,
+ &start, &stop), -EINVAL);
+ }
+}
+
+static void tlob_parse_out_of_range_rejected(struct kunit *test)
+{
+ u64 thr;
+ char *path;
+ loff_t start, stop;
+ char buf[128];
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(tlob_parse_out_of_range); i++) {
+ strscpy(buf, tlob_parse_out_of_range[i], sizeof(buf));
+ KUNIT_EXPECT_EQ(test, tlob_parse_uprobe_line(buf, &thr, &path,
+ &start, &stop), -ERANGE);
+ }
+}
+
+static void tlob_remove_valid_accepted(struct kunit *test)
+{
+ char *path;
+ loff_t start;
+ char buf[128];
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(tlob_remove_valid); i++) {
+ strscpy(buf, tlob_remove_valid[i], sizeof(buf));
+ KUNIT_EXPECT_EQ(test, tlob_parse_remove_line(buf, &path, &start), 0);
+ }
+}
+
+static void tlob_remove_invalid_rejected(struct kunit *test)
+{
+ char *path;
+ loff_t start;
+ char buf[128];
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(tlob_remove_invalid); i++) {
+ strscpy(buf, tlob_remove_invalid[i], sizeof(buf));
+ KUNIT_EXPECT_EQ(test, tlob_parse_remove_line(buf, &path, &start), -EINVAL);
+ }
+}
+
+static struct kunit_case tlob_parse_cases[] = {
+ KUNIT_CASE(tlob_parse_valid_accepted),
+ KUNIT_CASE(tlob_parse_invalid_rejected),
+ KUNIT_CASE(tlob_parse_out_of_range_rejected),
+ KUNIT_CASE(tlob_remove_valid_accepted),
+ KUNIT_CASE(tlob_remove_invalid_rejected),
+ {}
+};
+
+static struct kunit_suite tlob_parse_suite = {
+ .name = "tlob_parse",
+ .test_cases = tlob_parse_cases,
+};
+
+kunit_test_suite(tlob_parse_suite);
+
+MODULE_DESCRIPTION("KUnit tests for the tlob RV monitor");
+MODULE_LICENSE("GPL");
--
2.25.1
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.