xref: /openbmc/linux/lib/kunit/debugfs.c (revision 5e990887)
1e2219db2SAlan Maguire // SPDX-License-Identifier: GPL-2.0
2e2219db2SAlan Maguire /*
3e2219db2SAlan Maguire  * Copyright (c) 2020, Oracle and/or its affiliates.
4e2219db2SAlan Maguire  *    Author: Alan Maguire <alan.maguire@oracle.com>
5e2219db2SAlan Maguire  */
6e2219db2SAlan Maguire 
7e2219db2SAlan Maguire #include <linux/debugfs.h>
8e2219db2SAlan Maguire #include <linux/module.h>
9e2219db2SAlan Maguire 
10e2219db2SAlan Maguire #include <kunit/test.h>
11e2219db2SAlan Maguire 
12e2219db2SAlan Maguire #include "string-stream.h"
1323108f6aSArnd Bergmann #include "debugfs.h"
14e2219db2SAlan Maguire 
15e2219db2SAlan Maguire #define KUNIT_DEBUGFS_ROOT             "kunit"
16e2219db2SAlan Maguire #define KUNIT_DEBUGFS_RESULTS          "results"
17e2219db2SAlan Maguire 
18e2219db2SAlan Maguire /*
19e2219db2SAlan Maguire  * Create a debugfs representation of test suites:
20e2219db2SAlan Maguire  *
21e2219db2SAlan Maguire  * Path						Semantics
22e2219db2SAlan Maguire  * /sys/kernel/debug/kunit/<testsuite>/results	Show results of last run for
23e2219db2SAlan Maguire  *						testsuite
24e2219db2SAlan Maguire  *
25e2219db2SAlan Maguire  */
26e2219db2SAlan Maguire 
27e2219db2SAlan Maguire static struct dentry *debugfs_rootdir;
28e2219db2SAlan Maguire 
kunit_debugfs_cleanup(void)29e2219db2SAlan Maguire void kunit_debugfs_cleanup(void)
30e2219db2SAlan Maguire {
31e2219db2SAlan Maguire 	debugfs_remove_recursive(debugfs_rootdir);
32e2219db2SAlan Maguire }
33e2219db2SAlan Maguire 
kunit_debugfs_init(void)34e2219db2SAlan Maguire void kunit_debugfs_init(void)
35e2219db2SAlan Maguire {
36e2219db2SAlan Maguire 	if (!debugfs_rootdir)
37e2219db2SAlan Maguire 		debugfs_rootdir = debugfs_create_dir(KUNIT_DEBUGFS_ROOT, NULL);
38e2219db2SAlan Maguire }
39e2219db2SAlan Maguire 
debugfs_print_result(struct seq_file * seq,struct kunit_suite * suite,struct kunit_case * test_case)40e2219db2SAlan Maguire static void debugfs_print_result(struct seq_file *seq,
41e2219db2SAlan Maguire 				 struct kunit_suite *suite,
42e2219db2SAlan Maguire 				 struct kunit_case *test_case)
43e2219db2SAlan Maguire {
44e2219db2SAlan Maguire 	if (!test_case || !test_case->log)
45e2219db2SAlan Maguire 		return;
46e2219db2SAlan Maguire 
47e2219db2SAlan Maguire 	seq_printf(seq, "%s", test_case->log);
48e2219db2SAlan Maguire }
49e2219db2SAlan Maguire 
50e2219db2SAlan Maguire /*
51e2219db2SAlan Maguire  * /sys/kernel/debug/kunit/<testsuite>/results shows all results for testsuite.
52e2219db2SAlan Maguire  */
debugfs_print_results(struct seq_file * seq,void * v)53e2219db2SAlan Maguire static int debugfs_print_results(struct seq_file *seq, void *v)
54e2219db2SAlan Maguire {
55e2219db2SAlan Maguire 	struct kunit_suite *suite = (struct kunit_suite *)seq->private;
56*5e990887SRichard Fitzgerald 	enum kunit_status success;
57e2219db2SAlan Maguire 	struct kunit_case *test_case;
58e2219db2SAlan Maguire 
59f9a301c3SRae Moar 	if (!suite)
60e2219db2SAlan Maguire 		return 0;
61e2219db2SAlan Maguire 
62*5e990887SRichard Fitzgerald 	success = kunit_suite_has_succeeded(suite);
63*5e990887SRichard Fitzgerald 
64f9a301c3SRae Moar 	/* Print KTAP header so the debugfs log can be parsed as valid KTAP. */
65f9a301c3SRae Moar 	seq_puts(seq, "KTAP version 1\n");
66f9a301c3SRae Moar 	seq_puts(seq, "1..1\n");
67f9a301c3SRae Moar 
68f9a301c3SRae Moar 	/* Print suite header because it is not stored in the test logs. */
69f9a301c3SRae Moar 	seq_puts(seq, KUNIT_SUBTEST_INDENT "KTAP version 1\n");
70f9a301c3SRae Moar 	seq_printf(seq, KUNIT_SUBTEST_INDENT "# Subtest: %s\n", suite->name);
71f9a301c3SRae Moar 	seq_printf(seq, KUNIT_SUBTEST_INDENT "1..%zd\n", kunit_suite_num_test_cases(suite));
72e2219db2SAlan Maguire 
73e2219db2SAlan Maguire 	kunit_suite_for_each_test_case(suite, test_case)
74e2219db2SAlan Maguire 		debugfs_print_result(seq, suite, test_case);
75e2219db2SAlan Maguire 
76f9a301c3SRae Moar 	if (suite->log)
77f9a301c3SRae Moar 		seq_printf(seq, "%s", suite->log);
78f9a301c3SRae Moar 
796c738b52SRae Moar 	seq_printf(seq, "%s %d %s\n",
806d2426b2SDavid Gow 		   kunit_status_to_ok_not_ok(success), 1, suite->name);
81e2219db2SAlan Maguire 	return 0;
82e2219db2SAlan Maguire }
83e2219db2SAlan Maguire 
debugfs_release(struct inode * inode,struct file * file)84e2219db2SAlan Maguire static int debugfs_release(struct inode *inode, struct file *file)
85e2219db2SAlan Maguire {
86e2219db2SAlan Maguire 	return single_release(inode, file);
87e2219db2SAlan Maguire }
88e2219db2SAlan Maguire 
debugfs_results_open(struct inode * inode,struct file * file)89e2219db2SAlan Maguire static int debugfs_results_open(struct inode *inode, struct file *file)
90e2219db2SAlan Maguire {
91e2219db2SAlan Maguire 	struct kunit_suite *suite;
92e2219db2SAlan Maguire 
93e2219db2SAlan Maguire 	suite = (struct kunit_suite *)inode->i_private;
94e2219db2SAlan Maguire 
95e2219db2SAlan Maguire 	return single_open(file, debugfs_print_results, suite);
96e2219db2SAlan Maguire }
97e2219db2SAlan Maguire 
98e2219db2SAlan Maguire static const struct file_operations debugfs_results_fops = {
99e2219db2SAlan Maguire 	.open = debugfs_results_open,
100e2219db2SAlan Maguire 	.read = seq_read,
101e2219db2SAlan Maguire 	.llseek = seq_lseek,
102e2219db2SAlan Maguire 	.release = debugfs_release,
103e2219db2SAlan Maguire };
104e2219db2SAlan Maguire 
kunit_debugfs_create_suite(struct kunit_suite * suite)105e2219db2SAlan Maguire void kunit_debugfs_create_suite(struct kunit_suite *suite)
106e2219db2SAlan Maguire {
107e2219db2SAlan Maguire 	struct kunit_case *test_case;
108e2219db2SAlan Maguire 
109e2219db2SAlan Maguire 	/* Allocate logs before creating debugfs representation. */
110e2219db2SAlan Maguire 	suite->log = kzalloc(KUNIT_LOG_SIZE, GFP_KERNEL);
111e2219db2SAlan Maguire 	kunit_suite_for_each_test_case(suite, test_case)
112e2219db2SAlan Maguire 		test_case->log = kzalloc(KUNIT_LOG_SIZE, GFP_KERNEL);
113e2219db2SAlan Maguire 
114e2219db2SAlan Maguire 	suite->debugfs = debugfs_create_dir(suite->name, debugfs_rootdir);
115e2219db2SAlan Maguire 
116e2219db2SAlan Maguire 	debugfs_create_file(KUNIT_DEBUGFS_RESULTS, S_IFREG | 0444,
117e2219db2SAlan Maguire 			    suite->debugfs,
118e2219db2SAlan Maguire 			    suite, &debugfs_results_fops);
119e2219db2SAlan Maguire }
120e2219db2SAlan Maguire 
kunit_debugfs_destroy_suite(struct kunit_suite * suite)121e2219db2SAlan Maguire void kunit_debugfs_destroy_suite(struct kunit_suite *suite)
122e2219db2SAlan Maguire {
123e2219db2SAlan Maguire 	struct kunit_case *test_case;
124e2219db2SAlan Maguire 
125e2219db2SAlan Maguire 	debugfs_remove_recursive(suite->debugfs);
126e2219db2SAlan Maguire 	kfree(suite->log);
127e2219db2SAlan Maguire 	kunit_suite_for_each_test_case(suite, test_case)
128e2219db2SAlan Maguire 		kfree(test_case->log);
129e2219db2SAlan Maguire }
130