LCOV - code coverage report
Current view: top level - lib/kunit - test.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 157 267 58.8 %
Date: 2023-08-24 13:40:31 Functions: 16 31 51.6 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Base unit test (KUnit) API.
       4             :  *
       5             :  * Copyright (C) 2019, Google LLC.
       6             :  * Author: Brendan Higgins <brendanhiggins@google.com>
       7             :  */
       8             : 
       9             : #include <kunit/resource.h>
      10             : #include <kunit/test.h>
      11             : #include <kunit/test-bug.h>
      12             : #include <linux/kernel.h>
      13             : #include <linux/module.h>
      14             : #include <linux/moduleparam.h>
      15             : #include <linux/panic.h>
      16             : #include <linux/sched/debug.h>
      17             : #include <linux/sched.h>
      18             : 
      19             : #include "debugfs.h"
      20             : #include "hooks-impl.h"
      21             : #include "string-stream.h"
      22             : #include "try-catch-impl.h"
      23             : 
      24             : /*
      25             :  * Hook to fail the current test and print an error message to the log.
      26             :  */
      27           0 : void __printf(3, 4) __kunit_fail_current_test_impl(const char *file, int line, const char *fmt, ...)
      28             : {
      29             :         va_list args;
      30             :         int len;
      31             :         char *buffer;
      32             : 
      33           0 :         if (!current->kunit_test)
      34           0 :                 return;
      35             : 
      36           0 :         kunit_set_failure(current->kunit_test);
      37             : 
      38             :         /* kunit_err() only accepts literals, so evaluate the args first. */
      39           0 :         va_start(args, fmt);
      40           0 :         len = vsnprintf(NULL, 0, fmt, args) + 1;
      41           0 :         va_end(args);
      42             : 
      43           0 :         buffer = kunit_kmalloc(current->kunit_test, len, GFP_KERNEL);
      44           0 :         if (!buffer)
      45             :                 return;
      46             : 
      47           0 :         va_start(args, fmt);
      48           0 :         vsnprintf(buffer, len, fmt, args);
      49           0 :         va_end(args);
      50             : 
      51           0 :         kunit_err(current->kunit_test, "%s:%d: %s", file, line, buffer);
      52           0 :         kunit_kfree(current->kunit_test, buffer);
      53             : }
      54             : 
      55             : /*
      56             :  * Enable KUnit tests to run.
      57             :  */
      58             : #ifdef CONFIG_KUNIT_DEFAULT_ENABLED
      59             : static bool enable_param = true;
      60             : #else
      61             : static bool enable_param;
      62             : #endif
      63             : module_param_named(enable, enable_param, bool, 0);
      64             : MODULE_PARM_DESC(enable, "Enable KUnit tests");
      65             : 
      66             : /*
      67             :  * KUnit statistic mode:
      68             :  * 0 - disabled
      69             :  * 1 - only when there is more than one subtest
      70             :  * 2 - enabled
      71             :  */
      72             : static int kunit_stats_enabled = 1;
      73             : module_param_named(stats_enabled, kunit_stats_enabled, int, 0644);
      74             : MODULE_PARM_DESC(stats_enabled,
      75             :                   "Print test stats: never (0), only for multiple subtests (1), or always (2)");
      76             : 
      77             : struct kunit_result_stats {
      78             :         unsigned long passed;
      79             :         unsigned long skipped;
      80             :         unsigned long failed;
      81             :         unsigned long total;
      82             : };
      83             : 
      84             : static bool kunit_should_print_stats(struct kunit_result_stats stats)
      85             : {
      86          19 :         if (kunit_stats_enabled == 0)
      87             :                 return false;
      88             : 
      89          19 :         if (kunit_stats_enabled == 2)
      90             :                 return true;
      91             : 
      92          19 :         return (stats.total > 1);
      93             : }
      94             : 
      95          17 : static void kunit_print_test_stats(struct kunit *test,
      96             :                                    struct kunit_result_stats stats)
      97             : {
      98          34 :         if (!kunit_should_print_stats(stats))
      99             :                 return;
     100             : 
     101          17 :         kunit_log(KERN_INFO, test,
     102             :                   KUNIT_SUBTEST_INDENT
     103             :                   "# %s: pass:%lu fail:%lu skip:%lu total:%lu",
     104             :                   test->name,
     105             :                   stats.passed,
     106             :                   stats.failed,
     107             :                   stats.skipped,
     108             :                   stats.total);
     109             : }
     110             : 
     111             : /**
     112             :  * kunit_log_newline() - Add newline to the end of log if one is not
     113             :  * already present.
     114             :  * @log: The log to add the newline to.
     115             :  */
     116           0 : static void kunit_log_newline(char *log)
     117             : {
     118             :         int log_len, len_left;
     119             : 
     120           0 :         log_len = strlen(log);
     121           0 :         len_left = KUNIT_LOG_SIZE - log_len - 1;
     122             : 
     123           0 :         if (log_len > 0 && log[log_len - 1] != '\n')
     124           0 :                 strncat(log, "\n", len_left);
     125           0 : }
     126             : 
     127             : /*
     128             :  * Append formatted message to log, size of which is limited to
     129             :  * KUNIT_LOG_SIZE bytes (including null terminating byte).
     130             :  */
     131         150 : void kunit_log_append(char *log, const char *fmt, ...)
     132             : {
     133             :         va_list args;
     134             :         int len, log_len, len_left;
     135             : 
     136         150 :         if (!log)
     137         150 :                 return;
     138             : 
     139           0 :         log_len = strlen(log);
     140           0 :         len_left = KUNIT_LOG_SIZE - log_len - 1;
     141           0 :         if (len_left <= 0)
     142             :                 return;
     143             : 
     144             :         /* Evaluate length of line to add to log */
     145           0 :         va_start(args, fmt);
     146           0 :         len = vsnprintf(NULL, 0, fmt, args) + 1;
     147           0 :         va_end(args);
     148             : 
     149             :         /* Print formatted line to the log */
     150           0 :         va_start(args, fmt);
     151           0 :         vsnprintf(log + log_len, min(len, len_left), fmt, args);
     152           0 :         va_end(args);
     153             : 
     154             :         /* Add newline to end of log if not already present. */
     155           0 :         kunit_log_newline(log);
     156             : }
     157             : EXPORT_SYMBOL_GPL(kunit_log_append);
     158             : 
     159           0 : size_t kunit_suite_num_test_cases(struct kunit_suite *suite)
     160             : {
     161             :         struct kunit_case *test_case;
     162           1 :         size_t len = 0;
     163             : 
     164          18 :         kunit_suite_for_each_test_case(suite, test_case)
     165          17 :                 len++;
     166             : 
     167           0 :         return len;
     168             : }
     169             : EXPORT_SYMBOL_GPL(kunit_suite_num_test_cases);
     170             : 
     171           1 : static void kunit_print_suite_start(struct kunit_suite *suite)
     172             : {
     173             :         /*
     174             :          * We do not log the test suite header as doing so would
     175             :          * mean debugfs display would consist of the test suite
     176             :          * header prior to individual test results.
     177             :          * Hence directly printk the suite status, and we will
     178             :          * separately seq_printf() the suite header for the debugfs
     179             :          * representation.
     180             :          */
     181           1 :         pr_info(KUNIT_SUBTEST_INDENT "KTAP version 1\n");
     182           1 :         pr_info(KUNIT_SUBTEST_INDENT "# Subtest: %s\n",
     183             :                   suite->name);
     184           1 :         pr_info(KUNIT_SUBTEST_INDENT "1..%zd\n",
     185             :                   kunit_suite_num_test_cases(suite));
     186           1 : }
     187             : 
     188             : /* Currently supported test levels */
     189             : enum {
     190             :         KUNIT_LEVEL_SUITE = 0,
     191             :         KUNIT_LEVEL_CASE,
     192             :         KUNIT_LEVEL_CASE_PARAM,
     193             : };
     194             : 
     195          98 : static void kunit_print_ok_not_ok(struct kunit *test,
     196             :                                   unsigned int test_level,
     197             :                                   enum kunit_status status,
     198             :                                   size_t test_number,
     199             :                                   const char *description,
     200             :                                   const char *directive)
     201             : {
     202          98 :         const char *directive_header = (status == KUNIT_SKIPPED) ? " # SKIP " : "";
     203          98 :         const char *directive_body = (status == KUNIT_SKIPPED) ? directive : "";
     204             : 
     205             :         /*
     206             :          * When test is NULL assume that results are from the suite
     207             :          * and today suite results are expected at level 0 only.
     208             :          */
     209          98 :         WARN(!test && test_level, "suite test level can't be %u!\n", test_level);
     210             : 
     211             :         /*
     212             :          * We do not log the test suite results as doing so would
     213             :          * mean debugfs display would consist of an incorrect test
     214             :          * number. Hence directly printk the suite result, and we will
     215             :          * separately seq_printf() the suite results for the debugfs
     216             :          * representation.
     217             :          */
     218          98 :         if (!test)
     219           1 :                 pr_info("%s %zd %s%s%s\n",
     220             :                         kunit_status_to_ok_not_ok(status),
     221             :                         test_number, description, directive_header,
     222             :                         directive_body);
     223             :         else
     224         194 :                 kunit_log(KERN_INFO, test,
     225             :                           "%*s%s %zd %s%s%s",
     226             :                           KUNIT_INDENT_LEN * test_level, "",
     227             :                           kunit_status_to_ok_not_ok(status),
     228             :                           test_number, description, directive_header,
     229             :                           directive_body);
     230          98 : }
     231             : 
     232           0 : enum kunit_status kunit_suite_has_succeeded(struct kunit_suite *suite)
     233             : {
     234             :         const struct kunit_case *test_case;
     235           1 :         enum kunit_status status = KUNIT_SKIPPED;
     236             : 
     237           1 :         if (suite->suite_init_err)
     238             :                 return KUNIT_FAILURE;
     239             : 
     240          18 :         kunit_suite_for_each_test_case(suite, test_case) {
     241          17 :                 if (test_case->status == KUNIT_FAILURE)
     242             :                         return KUNIT_FAILURE;
     243          17 :                 else if (test_case->status == KUNIT_SUCCESS)
     244          17 :                         status = KUNIT_SUCCESS;
     245             :         }
     246             : 
     247             :         return status;
     248             : }
     249             : EXPORT_SYMBOL_GPL(kunit_suite_has_succeeded);
     250             : 
     251             : static size_t kunit_suite_counter = 1;
     252             : 
     253           1 : static void kunit_print_suite_end(struct kunit_suite *suite)
     254             : {
     255           2 :         kunit_print_ok_not_ok(NULL, KUNIT_LEVEL_SUITE,
     256             :                               kunit_suite_has_succeeded(suite),
     257             :                               kunit_suite_counter++,
     258           1 :                               suite->name,
     259           1 :                               suite->status_comment);
     260           1 : }
     261             : 
     262           0 : unsigned int kunit_test_case_num(struct kunit_suite *suite,
     263             :                                  struct kunit_case *test_case)
     264             : {
     265             :         struct kunit_case *tc;
     266          17 :         unsigned int i = 1;
     267             : 
     268         153 :         kunit_suite_for_each_test_case(suite, tc) {
     269         153 :                 if (tc == test_case)
     270             :                         return i;
     271         136 :                 i++;
     272             :         }
     273             : 
     274             :         return 0;
     275             : }
     276             : EXPORT_SYMBOL_GPL(kunit_test_case_num);
     277             : 
     278           0 : static void kunit_print_string_stream(struct kunit *test,
     279             :                                       struct string_stream *stream)
     280             : {
     281             :         struct string_stream_fragment *fragment;
     282             :         char *buf;
     283             : 
     284           0 :         if (string_stream_is_empty(stream))
     285             :                 return;
     286             : 
     287           0 :         buf = string_stream_get_string(stream);
     288           0 :         if (!buf) {
     289           0 :                 kunit_err(test,
     290             :                           "Could not allocate buffer, dumping stream:\n");
     291           0 :                 list_for_each_entry(fragment, &stream->fragments, node) {
     292           0 :                         kunit_err(test, "%s", fragment->fragment);
     293             :                 }
     294           0 :                 kunit_err(test, "\n");
     295             :         } else {
     296           0 :                 kunit_err(test, "%s", buf);
     297             :                 kunit_kfree(test, buf);
     298             :         }
     299             : }
     300             : 
     301           0 : static void kunit_fail(struct kunit *test, const struct kunit_loc *loc,
     302             :                        enum kunit_assert_type type, const struct kunit_assert *assert,
     303             :                        assert_format_t assert_format, const struct va_format *message)
     304             : {
     305             :         struct string_stream *stream;
     306             : 
     307           0 :         kunit_set_failure(test);
     308             : 
     309           0 :         stream = alloc_string_stream(test, GFP_KERNEL);
     310           0 :         if (IS_ERR(stream)) {
     311           0 :                 WARN(true,
     312             :                      "Could not allocate stream to print failed assertion in %s:%d\n",
     313             :                      loc->file,
     314             :                      loc->line);
     315           0 :                 return;
     316             :         }
     317             : 
     318           0 :         kunit_assert_prologue(loc, type, stream);
     319           0 :         assert_format(assert, message, stream);
     320             : 
     321           0 :         kunit_print_string_stream(test, stream);
     322             : 
     323           0 :         string_stream_destroy(stream);
     324             : }
     325             : 
     326           0 : void __noreturn __kunit_abort(struct kunit *test)
     327             : {
     328           0 :         kunit_try_catch_throw(&test->try_catch); /* Does not return. */
     329             : 
     330             :         /*
     331             :          * Throw could not abort from test.
     332             :          *
     333             :          * XXX: we should never reach this line! As kunit_try_catch_throw is
     334             :          * marked __noreturn.
     335             :          */
     336             :         WARN_ONCE(true, "Throw could not abort from test!\n");
     337             : }
     338             : EXPORT_SYMBOL_GPL(__kunit_abort);
     339             : 
     340           0 : void __kunit_do_failed_assertion(struct kunit *test,
     341             :                                const struct kunit_loc *loc,
     342             :                                enum kunit_assert_type type,
     343             :                                const struct kunit_assert *assert,
     344             :                                assert_format_t assert_format,
     345             :                                const char *fmt, ...)
     346             : {
     347             :         va_list args;
     348             :         struct va_format message;
     349           0 :         va_start(args, fmt);
     350             : 
     351           0 :         message.fmt = fmt;
     352           0 :         message.va = &args;
     353             : 
     354           0 :         kunit_fail(test, loc, type, assert, assert_format, &message);
     355             : 
     356           0 :         va_end(args);
     357           0 : }
     358             : EXPORT_SYMBOL_GPL(__kunit_do_failed_assertion);
     359             : 
     360           0 : void kunit_init_test(struct kunit *test, const char *name, char *log)
     361             : {
     362          17 :         spin_lock_init(&test->lock);
     363          34 :         INIT_LIST_HEAD(&test->resources);
     364          17 :         test->name = name;
     365          17 :         test->log = log;
     366          17 :         if (test->log)
     367           0 :                 test->log[0] = '\0';
     368          17 :         test->status = KUNIT_SUCCESS;
     369          17 :         test->status_comment[0] = '\0';
     370           0 : }
     371             : EXPORT_SYMBOL_GPL(kunit_init_test);
     372             : 
     373             : /*
     374             :  * Initializes and runs test case. Does not clean up or do post validations.
     375             :  */
     376          80 : static void kunit_run_case_internal(struct kunit *test,
     377             :                                     struct kunit_suite *suite,
     378             :                                     struct kunit_case *test_case)
     379             : {
     380          80 :         if (suite->init) {
     381             :                 int ret;
     382             : 
     383           0 :                 ret = suite->init(test);
     384           0 :                 if (ret) {
     385           0 :                         kunit_err(test, "failed to initialize: %d\n", ret);
     386             :                         kunit_set_failure(test);
     387             :                         return;
     388             :                 }
     389             :         }
     390             : 
     391          80 :         test_case->run_case(test);
     392             : }
     393             : 
     394             : static void kunit_case_internal_cleanup(struct kunit *test)
     395             : {
     396          80 :         kunit_cleanup(test);
     397             : }
     398             : 
     399             : /*
     400             :  * Performs post validations and cleanup after a test case was run.
     401             :  * XXX: Should ONLY BE CALLED AFTER kunit_run_case_internal!
     402             :  */
     403             : static void kunit_run_case_cleanup(struct kunit *test,
     404             :                                    struct kunit_suite *suite)
     405             : {
     406          80 :         if (suite->exit)
     407           0 :                 suite->exit(test);
     408             : 
     409          80 :         kunit_case_internal_cleanup(test);
     410             : }
     411             : 
     412             : struct kunit_try_catch_context {
     413             :         struct kunit *test;
     414             :         struct kunit_suite *suite;
     415             :         struct kunit_case *test_case;
     416             : };
     417             : 
     418          80 : static void kunit_try_run_case(void *data)
     419             : {
     420          80 :         struct kunit_try_catch_context *ctx = data;
     421          80 :         struct kunit *test = ctx->test;
     422          80 :         struct kunit_suite *suite = ctx->suite;
     423          80 :         struct kunit_case *test_case = ctx->test_case;
     424             : 
     425          80 :         current->kunit_test = test;
     426             : 
     427             :         /*
     428             :          * kunit_run_case_internal may encounter a fatal error; if it does,
     429             :          * abort will be called, this thread will exit, and finally the parent
     430             :          * thread will resume control and handle any necessary clean up.
     431             :          */
     432          80 :         kunit_run_case_internal(test, suite, test_case);
     433          80 : }
     434             : 
     435          80 : static void kunit_try_run_case_cleanup(void *data)
     436             : {
     437          80 :         struct kunit_try_catch_context *ctx = data;
     438          80 :         struct kunit *test = ctx->test;
     439          80 :         struct kunit_suite *suite = ctx->suite;
     440             : 
     441          80 :         current->kunit_test = test;
     442             : 
     443         160 :         kunit_run_case_cleanup(test, suite);
     444          80 : }
     445             : 
     446           0 : static void kunit_catch_run_case_cleanup(void *data)
     447             : {
     448           0 :         struct kunit_try_catch_context *ctx = data;
     449           0 :         struct kunit *test = ctx->test;
     450           0 :         int try_exit_code = kunit_try_catch_get_result(&test->try_catch);
     451             : 
     452             :         /* It is always a failure if cleanup aborts. */
     453           0 :         kunit_set_failure(test);
     454             : 
     455           0 :         if (try_exit_code) {
     456             :                 /*
     457             :                  * Test case could not finish, we have no idea what state it is
     458             :                  * in, so don't do clean up.
     459             :                  */
     460           0 :                 if (try_exit_code == -ETIMEDOUT) {
     461           0 :                         kunit_err(test, "test case cleanup timed out\n");
     462             :                 /*
     463             :                  * Unknown internal error occurred preventing test case from
     464             :                  * running, so there is nothing to clean up.
     465             :                  */
     466             :                 } else {
     467           0 :                         kunit_err(test, "internal error occurred during test case cleanup: %d\n",
     468             :                                   try_exit_code);
     469             :                 }
     470             :                 return;
     471             :         }
     472             : 
     473           0 :         kunit_err(test, "test aborted during cleanup. continuing without cleaning up\n");
     474             : }
     475             : 
     476             : 
     477           0 : static void kunit_catch_run_case(void *data)
     478             : {
     479           0 :         struct kunit_try_catch_context *ctx = data;
     480           0 :         struct kunit *test = ctx->test;
     481           0 :         int try_exit_code = kunit_try_catch_get_result(&test->try_catch);
     482             : 
     483           0 :         if (try_exit_code) {
     484           0 :                 kunit_set_failure(test);
     485             :                 /*
     486             :                  * Test case could not finish, we have no idea what state it is
     487             :                  * in, so don't do clean up.
     488             :                  */
     489           0 :                 if (try_exit_code == -ETIMEDOUT) {
     490           0 :                         kunit_err(test, "test case timed out\n");
     491             :                 /*
     492             :                  * Unknown internal error occurred preventing test case from
     493             :                  * running, so there is nothing to clean up.
     494             :                  */
     495             :                 } else {
     496           0 :                         kunit_err(test, "internal error occurred preventing test case from running: %d\n",
     497             :                                   try_exit_code);
     498             :                 }
     499             :                 return;
     500             :         }
     501             : }
     502             : 
     503             : /*
     504             :  * Performs all logic to run a test case. It also catches most errors that
     505             :  * occur in a test case and reports them as failures.
     506             :  */
     507          80 : static void kunit_run_case_catch_errors(struct kunit_suite *suite,
     508             :                                         struct kunit_case *test_case,
     509             :                                         struct kunit *test)
     510             : {
     511             :         struct kunit_try_catch_context context;
     512             :         struct kunit_try_catch *try_catch;
     513             : 
     514          80 :         try_catch = &test->try_catch;
     515             : 
     516          80 :         kunit_try_catch_init(try_catch,
     517             :                              test,
     518             :                              kunit_try_run_case,
     519             :                              kunit_catch_run_case);
     520          80 :         context.test = test;
     521          80 :         context.suite = suite;
     522          80 :         context.test_case = test_case;
     523          80 :         kunit_try_catch_run(try_catch, &context);
     524             : 
     525             :         /* Now run the cleanup */
     526          80 :         kunit_try_catch_init(try_catch,
     527             :                              test,
     528             :                              kunit_try_run_case_cleanup,
     529             :                              kunit_catch_run_case_cleanup);
     530          80 :         kunit_try_catch_run(try_catch, &context);
     531             : 
     532             :         /* Propagate the parameter result to the test case. */
     533          80 :         if (test->status == KUNIT_FAILURE)
     534           0 :                 test_case->status = KUNIT_FAILURE;
     535          80 :         else if (test_case->status != KUNIT_FAILURE && test->status == KUNIT_SUCCESS)
     536          80 :                 test_case->status = KUNIT_SUCCESS;
     537          80 : }
     538             : 
     539           1 : static void kunit_print_suite_stats(struct kunit_suite *suite,
     540             :                                     struct kunit_result_stats suite_stats,
     541             :                                     struct kunit_result_stats param_stats)
     542             : {
     543           2 :         if (kunit_should_print_stats(suite_stats)) {
     544           1 :                 kunit_log(KERN_INFO, suite,
     545             :                           "# %s: pass:%lu fail:%lu skip:%lu total:%lu",
     546             :                           suite->name,
     547             :                           suite_stats.passed,
     548             :                           suite_stats.failed,
     549             :                           suite_stats.skipped,
     550             :                           suite_stats.total);
     551             :         }
     552             : 
     553           2 :         if (kunit_should_print_stats(param_stats)) {
     554           1 :                 kunit_log(KERN_INFO, suite,
     555             :                           "# Totals: pass:%lu fail:%lu skip:%lu total:%lu",
     556             :                           param_stats.passed,
     557             :                           param_stats.failed,
     558             :                           param_stats.skipped,
     559             :                           param_stats.total);
     560             :         }
     561           1 : }
     562             : 
     563             : static void kunit_update_stats(struct kunit_result_stats *stats,
     564             :                                enum kunit_status status)
     565             : {
     566          97 :         switch (status) {
     567             :         case KUNIT_SUCCESS:
     568          97 :                 stats->passed++;
     569             :                 break;
     570             :         case KUNIT_SKIPPED:
     571           0 :                 stats->skipped++;
     572             :                 break;
     573             :         case KUNIT_FAILURE:
     574           0 :                 stats->failed++;
     575             :                 break;
     576             :         }
     577             : 
     578          97 :         stats->total++;
     579             : }
     580             : 
     581             : static void kunit_accumulate_stats(struct kunit_result_stats *total,
     582             :                                    struct kunit_result_stats add)
     583             : {
     584          17 :         total->passed += add.passed;
     585          17 :         total->skipped += add.skipped;
     586          17 :         total->failed += add.failed;
     587          17 :         total->total += add.total;
     588             : }
     589             : 
     590           1 : int kunit_run_tests(struct kunit_suite *suite)
     591             : {
     592             :         char param_desc[KUNIT_PARAM_DESC_SIZE];
     593             :         struct kunit_case *test_case;
     594           1 :         struct kunit_result_stats suite_stats = { 0 };
     595           1 :         struct kunit_result_stats total_stats = { 0 };
     596             : 
     597             :         /* Taint the kernel so we know we've run tests. */
     598           1 :         add_taint(TAINT_TEST, LOCKDEP_STILL_OK);
     599             : 
     600           1 :         if (suite->suite_init) {
     601           0 :                 suite->suite_init_err = suite->suite_init(suite);
     602           0 :                 if (suite->suite_init_err) {
     603           0 :                         kunit_err(suite, KUNIT_SUBTEST_INDENT
     604             :                                   "# failed to initialize (%d)", suite->suite_init_err);
     605           0 :                         goto suite_end;
     606             :                 }
     607             :         }
     608             : 
     609           1 :         kunit_print_suite_start(suite);
     610             : 
     611          18 :         kunit_suite_for_each_test_case(suite, test_case) {
     612          17 :                 struct kunit test = { .param_value = NULL, .param_index = 0 };
     613          17 :                 struct kunit_result_stats param_stats = { 0 };
     614          17 :                 test_case->status = KUNIT_SKIPPED;
     615             : 
     616          34 :                 kunit_init_test(&test, test_case->name, test_case->log);
     617             : 
     618          17 :                 if (!test_case->generate_params) {
     619             :                         /* Non-parameterised test. */
     620           0 :                         kunit_run_case_catch_errors(suite, test_case, &test);
     621           0 :                         kunit_update_stats(&param_stats, test.status);
     622             :                 } else {
     623             :                         /* Get initial param. */
     624          17 :                         param_desc[0] = '\0';
     625          17 :                         test.param_value = test_case->generate_params(NULL, param_desc);
     626          17 :                         kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
     627             :                                   "KTAP version 1\n");
     628          17 :                         kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
     629             :                                   "# Subtest: %s", test_case->name);
     630             : 
     631         114 :                         while (test.param_value) {
     632          80 :                                 kunit_run_case_catch_errors(suite, test_case, &test);
     633             : 
     634          80 :                                 if (param_desc[0] == '\0') {
     635           0 :                                         snprintf(param_desc, sizeof(param_desc),
     636             :                                                  "param-%d", test.param_index);
     637             :                                 }
     638             : 
     639          80 :                                 kunit_print_ok_not_ok(&test, KUNIT_LEVEL_CASE_PARAM,
     640             :                                                       test.status,
     641          80 :                                                       test.param_index + 1,
     642             :                                                       param_desc,
     643             :                                                       test.status_comment);
     644             : 
     645             :                                 /* Get next param. */
     646          80 :                                 param_desc[0] = '\0';
     647          80 :                                 test.param_value = test_case->generate_params(test.param_value, param_desc);
     648          80 :                                 test.param_index++;
     649             : 
     650          80 :                                 kunit_update_stats(&param_stats, test.status);
     651             :                         }
     652             :                 }
     653             : 
     654             : 
     655          17 :                 kunit_print_test_stats(&test, param_stats);
     656             : 
     657          34 :                 kunit_print_ok_not_ok(&test, KUNIT_LEVEL_CASE, test_case->status,
     658          17 :                                       kunit_test_case_num(suite, test_case),
     659             :                                       test_case->name,
     660             :                                       test.status_comment);
     661             : 
     662          34 :                 kunit_update_stats(&suite_stats, test_case->status);
     663          17 :                 kunit_accumulate_stats(&total_stats, param_stats);
     664             :         }
     665             : 
     666           1 :         if (suite->suite_exit)
     667           0 :                 suite->suite_exit(suite);
     668             : 
     669           1 :         kunit_print_suite_stats(suite, suite_stats, total_stats);
     670             : suite_end:
     671           1 :         kunit_print_suite_end(suite);
     672             : 
     673           1 :         return 0;
     674             : }
     675             : EXPORT_SYMBOL_GPL(kunit_run_tests);
     676             : 
     677             : static void kunit_init_suite(struct kunit_suite *suite)
     678             : {
     679           1 :         kunit_debugfs_create_suite(suite);
     680           1 :         suite->status_comment[0] = '\0';
     681           1 :         suite->suite_init_err = 0;
     682             : }
     683             : 
     684           1 : bool kunit_enabled(void)
     685             : {
     686           2 :         return enable_param;
     687             : }
     688             : 
     689           1 : int __kunit_test_suites_init(struct kunit_suite * const * const suites, int num_suites)
     690             : {
     691             :         unsigned int i;
     692             : 
     693           1 :         if (!kunit_enabled() && num_suites > 0) {
     694           0 :                 pr_info("kunit: disabled\n");
     695           0 :                 return 0;
     696             :         }
     697             : 
     698           1 :         static_branch_inc(&kunit_running);
     699             : 
     700           2 :         for (i = 0; i < num_suites; i++) {
     701           1 :                 kunit_init_suite(suites[i]);
     702           1 :                 kunit_run_tests(suites[i]);
     703             :         }
     704             : 
     705           1 :         static_branch_dec(&kunit_running);
     706           1 :         return 0;
     707             : }
     708             : EXPORT_SYMBOL_GPL(__kunit_test_suites_init);
     709             : 
     710             : static void kunit_exit_suite(struct kunit_suite *suite)
     711             : {
     712             :         kunit_debugfs_destroy_suite(suite);
     713             : }
     714             : 
     715           0 : void __kunit_test_suites_exit(struct kunit_suite **suites, int num_suites)
     716             : {
     717             :         unsigned int i;
     718             : 
     719           0 :         if (!kunit_enabled())
     720             :                 return;
     721             : 
     722             :         for (i = 0; i < num_suites; i++)
     723             :                 kunit_exit_suite(suites[i]);
     724             : 
     725           0 :         kunit_suite_counter = 1;
     726             : }
     727             : EXPORT_SYMBOL_GPL(__kunit_test_suites_exit);
     728             : 
     729             : #ifdef CONFIG_MODULES
     730             : static void kunit_module_init(struct module *mod)
     731             : {
     732             :         __kunit_test_suites_init(mod->kunit_suites, mod->num_kunit_suites);
     733             : }
     734             : 
     735             : static void kunit_module_exit(struct module *mod)
     736             : {
     737             :         __kunit_test_suites_exit(mod->kunit_suites, mod->num_kunit_suites);
     738             : }
     739             : 
     740             : static int kunit_module_notify(struct notifier_block *nb, unsigned long val,
     741             :                                void *data)
     742             : {
     743             :         struct module *mod = data;
     744             : 
     745             :         switch (val) {
     746             :         case MODULE_STATE_LIVE:
     747             :                 kunit_module_init(mod);
     748             :                 break;
     749             :         case MODULE_STATE_GOING:
     750             :                 kunit_module_exit(mod);
     751             :                 break;
     752             :         case MODULE_STATE_COMING:
     753             :         case MODULE_STATE_UNFORMED:
     754             :                 break;
     755             :         }
     756             : 
     757             :         return 0;
     758             : }
     759             : 
     760             : static struct notifier_block kunit_mod_nb = {
     761             :         .notifier_call = kunit_module_notify,
     762             :         .priority = 0,
     763             : };
     764             : #endif
     765             : 
     766         293 : void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t gfp)
     767             : {
     768             :         void *data;
     769             : 
     770         293 :         data = kmalloc_array(n, size, gfp);
     771             : 
     772         293 :         if (!data)
     773             :                 return NULL;
     774             : 
     775         293 :         if (kunit_add_action_or_reset(test, (kunit_action_t *)kfree, data) != 0)
     776             :                 return NULL;
     777             : 
     778         293 :         return data;
     779             : }
     780             : EXPORT_SYMBOL_GPL(kunit_kmalloc_array);
     781             : 
     782           0 : void kunit_kfree(struct kunit *test, const void *ptr)
     783             : {
     784           0 :         if (!ptr)
     785             :                 return;
     786             : 
     787           0 :         kunit_release_action(test, (kunit_action_t *)kfree, (void *)ptr);
     788             : }
     789             : EXPORT_SYMBOL_GPL(kunit_kfree);
     790             : 
     791          80 : void kunit_cleanup(struct kunit *test)
     792             : {
     793             :         struct kunit_resource *res;
     794             :         unsigned long flags;
     795             : 
     796             :         /*
     797             :          * test->resources is a stack - each allocation must be freed in the
     798             :          * reverse order from which it was added since one resource may depend
     799             :          * on another for its entire lifetime.
     800             :          * Also, we cannot use the normal list_for_each constructs, even the
     801             :          * safe ones because *arbitrary* nodes may be deleted when
     802             :          * kunit_resource_free is called; the list_for_each_safe variants only
     803             :          * protect against the current node being deleted, not the next.
     804             :          */
     805             :         while (true) {
     806         696 :                 spin_lock_irqsave(&test->lock, flags);
     807         776 :                 if (list_empty(&test->resources)) {
     808         160 :                         spin_unlock_irqrestore(&test->lock, flags);
     809             :                         break;
     810             :                 }
     811         308 :                 res = list_last_entry(&test->resources,
     812             :                                       struct kunit_resource,
     813             :                                       node);
     814             :                 /*
     815             :                  * Need to unlock here as a resource may remove another
     816             :                  * resource, and this can't happen if the test->lock
     817             :                  * is held.
     818             :                  */
     819         616 :                 spin_unlock_irqrestore(&test->lock, flags);
     820         308 :                 kunit_remove_resource(test, res);
     821             :         }
     822          80 :         current->kunit_test = NULL;
     823          80 : }
     824             : EXPORT_SYMBOL_GPL(kunit_cleanup);
     825             : 
     826           1 : static int __init kunit_init(void)
     827             : {
     828             :         /* Install the KUnit hook functions. */
     829             :         kunit_install_hooks();
     830             : 
     831             :         kunit_debugfs_init();
     832             : #ifdef CONFIG_MODULES
     833             :         return register_module_notifier(&kunit_mod_nb);
     834             : #else
     835           1 :         return 0;
     836             : #endif
     837             : }
     838             : late_initcall(kunit_init);
     839             : 
     840           0 : static void __exit kunit_exit(void)
     841             : {
     842           0 :         memset(&kunit_hooks, 0, sizeof(kunit_hooks));
     843             : #ifdef CONFIG_MODULES
     844             :         unregister_module_notifier(&kunit_mod_nb);
     845             : #endif
     846             :         kunit_debugfs_cleanup();
     847           0 : }
     848             : module_exit(kunit_exit);
     849             : 
     850             : MODULE_LICENSE("GPL v2");

Generated by: LCOV version 1.14