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