1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2020, Oracle and/or its affiliates.
4 * Author: Alan Maguire <alan.maguire@oracle.com>
7 #include <linux/debugfs.h>
8 #include <linux/module.h>
10 #include <kunit/test.h>
11 #include <kunit/test-bug.h>
13 #include "string-stream.h"
16 #define KUNIT_DEBUGFS_ROOT "kunit"
17 #define KUNIT_DEBUGFS_RESULTS "results"
18 #define KUNIT_DEBUGFS_RUN "run"
21 * Create a debugfs representation of test suites:
24 * /sys/kernel/debug/kunit/<testsuite>/results Show results of last run for
26 * /sys/kernel/debug/kunit/<testsuite>/run Write to this file to trigger
31 static struct dentry
*debugfs_rootdir
;
33 void kunit_debugfs_cleanup(void)
35 debugfs_remove_recursive(debugfs_rootdir
);
38 void kunit_debugfs_init(void)
41 debugfs_rootdir
= debugfs_create_dir(KUNIT_DEBUGFS_ROOT
, NULL
);
44 static void debugfs_print_result(struct seq_file
*seq
, struct string_stream
*log
)
46 struct string_stream_fragment
*frag_container
;
52 * Walk the fragments so we don't need to allocate a temporary
53 * buffer to hold the entire string.
55 spin_lock(&log
->lock
);
56 list_for_each_entry(frag_container
, &log
->fragments
, node
)
57 seq_printf(seq
, "%s", frag_container
->fragment
);
58 spin_unlock(&log
->lock
);
62 * /sys/kernel/debug/kunit/<testsuite>/results shows all results for testsuite.
64 static int debugfs_print_results(struct seq_file
*seq
, void *v
)
66 struct kunit_suite
*suite
= (struct kunit_suite
*)seq
->private;
67 enum kunit_status success
;
68 struct kunit_case
*test_case
;
73 success
= kunit_suite_has_succeeded(suite
);
75 /* Print KTAP header so the debugfs log can be parsed as valid KTAP. */
76 seq_puts(seq
, "KTAP version 1\n");
77 seq_puts(seq
, "1..1\n");
79 /* Print suite header because it is not stored in the test logs. */
80 seq_puts(seq
, KUNIT_SUBTEST_INDENT
"KTAP version 1\n");
81 seq_printf(seq
, KUNIT_SUBTEST_INDENT
"# Subtest: %s\n", suite
->name
);
82 seq_printf(seq
, KUNIT_SUBTEST_INDENT
"1..%zd\n", kunit_suite_num_test_cases(suite
));
84 kunit_suite_for_each_test_case(suite
, test_case
)
85 debugfs_print_result(seq
, test_case
->log
);
87 debugfs_print_result(seq
, suite
->log
);
89 seq_printf(seq
, "%s %d %s\n",
90 kunit_status_to_ok_not_ok(success
), 1, suite
->name
);
94 static int debugfs_release(struct inode
*inode
, struct file
*file
)
96 return single_release(inode
, file
);
99 static int debugfs_results_open(struct inode
*inode
, struct file
*file
)
101 struct kunit_suite
*suite
;
103 suite
= (struct kunit_suite
*)inode
->i_private
;
105 return single_open(file
, debugfs_print_results
, suite
);
109 * Print a usage message to the debugfs "run" file
110 * (/sys/kernel/debug/kunit/<testsuite>/run) if opened.
112 static int debugfs_print_run(struct seq_file
*seq
, void *v
)
114 struct kunit_suite
*suite
= (struct kunit_suite
*)seq
->private;
116 seq_puts(seq
, "Write to this file to trigger the test suite to run.\n");
117 seq_printf(seq
, "usage: echo \"any string\" > /sys/kernel/debugfs/kunit/%s/run\n",
123 * The debugfs "run" file (/sys/kernel/debug/kunit/<testsuite>/run)
124 * contains no information. Write to the file to trigger the test suite
127 static int debugfs_run_open(struct inode
*inode
, struct file
*file
)
129 struct kunit_suite
*suite
;
131 suite
= (struct kunit_suite
*)inode
->i_private
;
133 return single_open(file
, debugfs_print_run
, suite
);
137 * Trigger a test suite to run by writing to the suite's "run" debugfs
138 * file found at: /sys/kernel/debug/kunit/<testsuite>/run
140 * Note: what is written to this file will not be saved.
142 static ssize_t
debugfs_run(struct file
*file
,
143 const char __user
*buf
, size_t count
, loff_t
*ppos
)
145 struct inode
*f_inode
= file
->f_inode
;
146 struct kunit_suite
*suite
= (struct kunit_suite
*) f_inode
->i_private
;
148 __kunit_test_suites_init(&suite
, 1);
153 static const struct file_operations debugfs_results_fops
= {
154 .open
= debugfs_results_open
,
157 .release
= debugfs_release
,
160 static const struct file_operations debugfs_run_fops
= {
161 .open
= debugfs_run_open
,
163 .write
= debugfs_run
,
165 .release
= debugfs_release
,
168 void kunit_debugfs_create_suite(struct kunit_suite
*suite
)
170 struct kunit_case
*test_case
;
171 struct string_stream
*stream
;
173 /* If suite log already allocated, do not create new debugfs files. */
178 * Allocate logs before creating debugfs representation.
179 * The suite->log and test_case->log pointer are expected to be NULL
180 * if there isn't a log, so only set it if the log stream was created
183 stream
= alloc_string_stream(GFP_KERNEL
);
187 string_stream_set_append_newlines(stream
, true);
190 kunit_suite_for_each_test_case(suite
, test_case
) {
191 stream
= alloc_string_stream(GFP_KERNEL
);
195 string_stream_set_append_newlines(stream
, true);
196 test_case
->log
= stream
;
199 suite
->debugfs
= debugfs_create_dir(suite
->name
, debugfs_rootdir
);
201 debugfs_create_file(KUNIT_DEBUGFS_RESULTS
, S_IFREG
| 0444,
203 suite
, &debugfs_results_fops
);
205 /* Do not create file to re-run test if test runs on init */
206 if (!suite
->is_init
) {
207 debugfs_create_file(KUNIT_DEBUGFS_RUN
, S_IFREG
| 0644,
209 suite
, &debugfs_run_fops
);
214 string_stream_destroy(suite
->log
);
216 kunit_suite_for_each_test_case(suite
, test_case
) {
217 string_stream_destroy(test_case
->log
);
218 test_case
->log
= NULL
;
222 void kunit_debugfs_destroy_suite(struct kunit_suite
*suite
)
224 struct kunit_case
*test_case
;
226 debugfs_remove_recursive(suite
->debugfs
);
227 string_stream_destroy(suite
->log
);
228 kunit_suite_for_each_test_case(suite
, test_case
)
229 string_stream_destroy(test_case
->log
);