LCOV - code coverage report
Current view: top level - lib/kunit - test.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 161 260 61.9 %
Date: 2023-07-19 18:55:55 Functions: 17 31 54.8 %

          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         181 :         if (kunit_stats_enabled == 0)
      87             :                 return false;
      88             : 
      89         181 :         if (kunit_stats_enabled == 2)
      90             :                 return true;
      91             : 
      92         181 :         return (stats.total > 1);
      93             : }
      94             : 
      95         149 : static void kunit_print_test_stats(struct kunit *test,
      96             :                                    struct kunit_result_stats stats)
      97             : {
      98         298 :         if (!kunit_should_print_stats(stats))
      99             :                 return;
     100             : 
     101          30 :         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         519 : void kunit_log_append(char *log, const char *fmt, ...)
     132             : {
     133             :         va_list args;
     134             :         int len, log_len, len_left;
     135             : 
     136         519 :         if (!log)
     137         519 :                 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          16 :         size_t len = 0;
     163             : 
     164         165 :         kunit_suite_for_each_test_case(suite, test_case)
     165         149 :                 len++;
     166             : 
     167           0 :         return len;
     168             : }
     169             : EXPORT_SYMBOL_GPL(kunit_suite_num_test_cases);
     170             : 
     171          16 : 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          16 :         pr_info(KUNIT_SUBTEST_INDENT "KTAP version 1\n");
     182          16 :         pr_info(KUNIT_SUBTEST_INDENT "# Subtest: %s\n",
     183             :                   suite->name);
     184          16 :         pr_info(KUNIT_SUBTEST_INDENT "1..%zd\n",
     185             :                   kunit_suite_num_test_cases(suite));
     186          16 : }
     187             : 
     188         165 : static void kunit_print_ok_not_ok(void *test_or_suite,
     189             :                                   bool is_test,
     190             :                                   enum kunit_status status,
     191             :                                   size_t test_number,
     192             :                                   const char *description,
     193             :                                   const char *directive)
     194             : {
     195         165 :         struct kunit_suite *suite = is_test ? NULL : test_or_suite;
     196         165 :         struct kunit *test = is_test ? test_or_suite : NULL;
     197         165 :         const char *directive_header = (status == KUNIT_SKIPPED) ? " # SKIP " : "";
     198             : 
     199             :         /*
     200             :          * We do not log the test suite results as doing so would
     201             :          * mean debugfs display would consist of an incorrect test
     202             :          * number. Hence directly printk the suite result, and we will
     203             :          * separately seq_printf() the suite results for the debugfs
     204             :          * representation.
     205             :          */
     206         165 :         if (suite)
     207          32 :                 pr_info("%s %zd %s%s%s\n",
     208             :                         kunit_status_to_ok_not_ok(status),
     209             :                         test_number, description, directive_header,
     210             :                         (status == KUNIT_SKIPPED) ? directive : "");
     211             :         else
     212         447 :                 kunit_log(KERN_INFO, test,
     213             :                           KUNIT_SUBTEST_INDENT "%s %zd %s%s%s",
     214             :                           kunit_status_to_ok_not_ok(status),
     215             :                           test_number, description, directive_header,
     216             :                           (status == KUNIT_SKIPPED) ? directive : "");
     217         165 : }
     218             : 
     219           0 : enum kunit_status kunit_suite_has_succeeded(struct kunit_suite *suite)
     220             : {
     221             :         const struct kunit_case *test_case;
     222          16 :         enum kunit_status status = KUNIT_SKIPPED;
     223             : 
     224          16 :         if (suite->suite_init_err)
     225             :                 return KUNIT_FAILURE;
     226             : 
     227         165 :         kunit_suite_for_each_test_case(suite, test_case) {
     228         149 :                 if (test_case->status == KUNIT_FAILURE)
     229             :                         return KUNIT_FAILURE;
     230         149 :                 else if (test_case->status == KUNIT_SUCCESS)
     231         149 :                         status = KUNIT_SUCCESS;
     232             :         }
     233             : 
     234             :         return status;
     235             : }
     236             : EXPORT_SYMBOL_GPL(kunit_suite_has_succeeded);
     237             : 
     238             : static size_t kunit_suite_counter = 1;
     239             : 
     240          16 : static void kunit_print_suite_end(struct kunit_suite *suite)
     241             : {
     242          32 :         kunit_print_ok_not_ok((void *)suite, false,
     243             :                               kunit_suite_has_succeeded(suite),
     244             :                               kunit_suite_counter++,
     245          16 :                               suite->name,
     246          16 :                               suite->status_comment);
     247          16 : }
     248             : 
     249           0 : unsigned int kunit_test_case_num(struct kunit_suite *suite,
     250             :                                  struct kunit_case *test_case)
     251             : {
     252             :         struct kunit_case *tc;
     253         149 :         unsigned int i = 1;
     254             : 
     255        1644 :         kunit_suite_for_each_test_case(suite, tc) {
     256        1644 :                 if (tc == test_case)
     257             :                         return i;
     258        1495 :                 i++;
     259             :         }
     260             : 
     261             :         return 0;
     262             : }
     263             : EXPORT_SYMBOL_GPL(kunit_test_case_num);
     264             : 
     265           0 : static void kunit_print_string_stream(struct kunit *test,
     266             :                                       struct string_stream *stream)
     267             : {
     268             :         struct string_stream_fragment *fragment;
     269             :         char *buf;
     270             : 
     271           0 :         if (string_stream_is_empty(stream))
     272             :                 return;
     273             : 
     274           0 :         buf = string_stream_get_string(stream);
     275           0 :         if (!buf) {
     276           0 :                 kunit_err(test,
     277             :                           "Could not allocate buffer, dumping stream:\n");
     278           0 :                 list_for_each_entry(fragment, &stream->fragments, node) {
     279           0 :                         kunit_err(test, "%s", fragment->fragment);
     280             :                 }
     281           0 :                 kunit_err(test, "\n");
     282             :         } else {
     283           0 :                 kunit_err(test, "%s", buf);
     284           0 :                 kunit_kfree(test, buf);
     285             :         }
     286             : }
     287             : 
     288           0 : static void kunit_fail(struct kunit *test, const struct kunit_loc *loc,
     289             :                        enum kunit_assert_type type, const struct kunit_assert *assert,
     290             :                        assert_format_t assert_format, const struct va_format *message)
     291             : {
     292             :         struct string_stream *stream;
     293             : 
     294           0 :         kunit_set_failure(test);
     295             : 
     296           0 :         stream = alloc_string_stream(test, GFP_KERNEL);
     297           0 :         if (IS_ERR(stream)) {
     298           0 :                 WARN(true,
     299             :                      "Could not allocate stream to print failed assertion in %s:%d\n",
     300             :                      loc->file,
     301             :                      loc->line);
     302           0 :                 return;
     303             :         }
     304             : 
     305           0 :         kunit_assert_prologue(loc, type, stream);
     306           0 :         assert_format(assert, message, stream);
     307             : 
     308           0 :         kunit_print_string_stream(test, stream);
     309             : 
     310           0 :         string_stream_destroy(stream);
     311             : }
     312             : 
     313             : static void __noreturn kunit_abort(struct kunit *test)
     314             : {
     315           0 :         kunit_try_catch_throw(&test->try_catch); /* Does not return. */
     316             : 
     317             :         /*
     318             :          * Throw could not abort from test.
     319             :          *
     320             :          * XXX: we should never reach this line! As kunit_try_catch_throw is
     321             :          * marked __noreturn.
     322             :          */
     323             :         WARN_ONCE(true, "Throw could not abort from test!\n");
     324             : }
     325             : 
     326           0 : void kunit_do_failed_assertion(struct kunit *test,
     327             :                                const struct kunit_loc *loc,
     328             :                                enum kunit_assert_type type,
     329             :                                const struct kunit_assert *assert,
     330             :                                assert_format_t assert_format,
     331             :                                const char *fmt, ...)
     332             : {
     333             :         va_list args;
     334             :         struct va_format message;
     335           0 :         va_start(args, fmt);
     336             : 
     337           0 :         message.fmt = fmt;
     338           0 :         message.va = &args;
     339             : 
     340           0 :         kunit_fail(test, loc, type, assert, assert_format, &message);
     341             : 
     342           0 :         va_end(args);
     343             : 
     344           0 :         if (type == KUNIT_ASSERTION)
     345             :                 kunit_abort(test);
     346           0 : }
     347             : EXPORT_SYMBOL_GPL(kunit_do_failed_assertion);
     348             : 
     349           0 : void kunit_init_test(struct kunit *test, const char *name, char *log)
     350             : {
     351         149 :         spin_lock_init(&test->lock);
     352         298 :         INIT_LIST_HEAD(&test->resources);
     353         149 :         test->name = name;
     354         149 :         test->log = log;
     355         149 :         if (test->log)
     356           0 :                 test->log[0] = '\0';
     357         149 :         test->status = KUNIT_SUCCESS;
     358         149 :         test->status_comment[0] = '\0';
     359           0 : }
     360             : EXPORT_SYMBOL_GPL(kunit_init_test);
     361             : 
     362             : /*
     363             :  * Initializes and runs test case. Does not clean up or do post validations.
     364             :  */
     365         367 : static void kunit_run_case_internal(struct kunit *test,
     366             :                                     struct kunit_suite *suite,
     367             :                                     struct kunit_case *test_case)
     368             : {
     369         367 :         if (suite->init) {
     370             :                 int ret;
     371             : 
     372          96 :                 ret = suite->init(test);
     373          96 :                 if (ret) {
     374           0 :                         kunit_err(test, "failed to initialize: %d\n", ret);
     375             :                         kunit_set_failure(test);
     376             :                         return;
     377             :                 }
     378             :         }
     379             : 
     380         367 :         test_case->run_case(test);
     381             : }
     382             : 
     383             : static void kunit_case_internal_cleanup(struct kunit *test)
     384             : {
     385         367 :         kunit_cleanup(test);
     386             : }
     387             : 
     388             : /*
     389             :  * Performs post validations and cleanup after a test case was run.
     390             :  * XXX: Should ONLY BE CALLED AFTER kunit_run_case_internal!
     391             :  */
     392             : static void kunit_run_case_cleanup(struct kunit *test,
     393             :                                    struct kunit_suite *suite)
     394             : {
     395         367 :         if (suite->exit)
     396          16 :                 suite->exit(test);
     397             : 
     398         367 :         kunit_case_internal_cleanup(test);
     399             : }
     400             : 
     401             : struct kunit_try_catch_context {
     402             :         struct kunit *test;
     403             :         struct kunit_suite *suite;
     404             :         struct kunit_case *test_case;
     405             : };
     406             : 
     407         367 : static void kunit_try_run_case(void *data)
     408             : {
     409         367 :         struct kunit_try_catch_context *ctx = data;
     410         367 :         struct kunit *test = ctx->test;
     411         367 :         struct kunit_suite *suite = ctx->suite;
     412         367 :         struct kunit_case *test_case = ctx->test_case;
     413             : 
     414         367 :         current->kunit_test = test;
     415             : 
     416             :         /*
     417             :          * kunit_run_case_internal may encounter a fatal error; if it does,
     418             :          * abort will be called, this thread will exit, and finally the parent
     419             :          * thread will resume control and handle any necessary clean up.
     420             :          */
     421         367 :         kunit_run_case_internal(test, suite, test_case);
     422             :         /* This line may never be reached. */
     423         734 :         kunit_run_case_cleanup(test, suite);
     424         367 : }
     425             : 
     426           0 : static void kunit_catch_run_case(void *data)
     427             : {
     428           0 :         struct kunit_try_catch_context *ctx = data;
     429           0 :         struct kunit *test = ctx->test;
     430           0 :         struct kunit_suite *suite = ctx->suite;
     431           0 :         int try_exit_code = kunit_try_catch_get_result(&test->try_catch);
     432             : 
     433           0 :         if (try_exit_code) {
     434           0 :                 kunit_set_failure(test);
     435             :                 /*
     436             :                  * Test case could not finish, we have no idea what state it is
     437             :                  * in, so don't do clean up.
     438             :                  */
     439           0 :                 if (try_exit_code == -ETIMEDOUT) {
     440           0 :                         kunit_err(test, "test case timed out\n");
     441             :                 /*
     442             :                  * Unknown internal error occurred preventing test case from
     443             :                  * running, so there is nothing to clean up.
     444             :                  */
     445             :                 } else {
     446           0 :                         kunit_err(test, "internal error occurred preventing test case from running: %d\n",
     447             :                                   try_exit_code);
     448             :                 }
     449             :                 return;
     450             :         }
     451             : 
     452             :         /*
     453             :          * Test case was run, but aborted. It is the test case's business as to
     454             :          * whether it failed or not, we just need to clean up.
     455             :          */
     456           0 :         kunit_run_case_cleanup(test, suite);
     457             : }
     458             : 
     459             : /*
     460             :  * Performs all logic to run a test case. It also catches most errors that
     461             :  * occur in a test case and reports them as failures.
     462             :  */
     463         367 : static void kunit_run_case_catch_errors(struct kunit_suite *suite,
     464             :                                         struct kunit_case *test_case,
     465             :                                         struct kunit *test)
     466             : {
     467             :         struct kunit_try_catch_context context;
     468             :         struct kunit_try_catch *try_catch;
     469             : 
     470         367 :         try_catch = &test->try_catch;
     471             : 
     472         367 :         kunit_try_catch_init(try_catch,
     473             :                              test,
     474             :                              kunit_try_run_case,
     475             :                              kunit_catch_run_case);
     476         367 :         context.test = test;
     477         367 :         context.suite = suite;
     478         367 :         context.test_case = test_case;
     479         367 :         kunit_try_catch_run(try_catch, &context);
     480             : 
     481             :         /* Propagate the parameter result to the test case. */
     482         367 :         if (test->status == KUNIT_FAILURE)
     483           0 :                 test_case->status = KUNIT_FAILURE;
     484         367 :         else if (test_case->status != KUNIT_FAILURE && test->status == KUNIT_SUCCESS)
     485         367 :                 test_case->status = KUNIT_SUCCESS;
     486         367 : }
     487             : 
     488          16 : static void kunit_print_suite_stats(struct kunit_suite *suite,
     489             :                                     struct kunit_result_stats suite_stats,
     490             :                                     struct kunit_result_stats param_stats)
     491             : {
     492          32 :         if (kunit_should_print_stats(suite_stats)) {
     493          13 :                 kunit_log(KERN_INFO, suite,
     494             :                           "# %s: pass:%lu fail:%lu skip:%lu total:%lu",
     495             :                           suite->name,
     496             :                           suite_stats.passed,
     497             :                           suite_stats.failed,
     498             :                           suite_stats.skipped,
     499             :                           suite_stats.total);
     500             :         }
     501             : 
     502          32 :         if (kunit_should_print_stats(param_stats)) {
     503          15 :                 kunit_log(KERN_INFO, suite,
     504             :                           "# Totals: pass:%lu fail:%lu skip:%lu total:%lu",
     505             :                           param_stats.passed,
     506             :                           param_stats.failed,
     507             :                           param_stats.skipped,
     508             :                           param_stats.total);
     509             :         }
     510          16 : }
     511             : 
     512             : static void kunit_update_stats(struct kunit_result_stats *stats,
     513             :                                enum kunit_status status)
     514             : {
     515         516 :         switch (status) {
     516             :         case KUNIT_SUCCESS:
     517         516 :                 stats->passed++;
     518             :                 break;
     519             :         case KUNIT_SKIPPED:
     520           0 :                 stats->skipped++;
     521             :                 break;
     522             :         case KUNIT_FAILURE:
     523           0 :                 stats->failed++;
     524             :                 break;
     525             :         }
     526             : 
     527         397 :         stats->total++;
     528             : }
     529             : 
     530             : static void kunit_accumulate_stats(struct kunit_result_stats *total,
     531             :                                    struct kunit_result_stats add)
     532             : {
     533         149 :         total->passed += add.passed;
     534         149 :         total->skipped += add.skipped;
     535         149 :         total->failed += add.failed;
     536         149 :         total->total += add.total;
     537             : }
     538             : 
     539          16 : int kunit_run_tests(struct kunit_suite *suite)
     540             : {
     541             :         char param_desc[KUNIT_PARAM_DESC_SIZE];
     542             :         struct kunit_case *test_case;
     543          16 :         struct kunit_result_stats suite_stats = { 0 };
     544          16 :         struct kunit_result_stats total_stats = { 0 };
     545             : 
     546             :         /* Taint the kernel so we know we've run tests. */
     547          16 :         add_taint(TAINT_TEST, LOCKDEP_STILL_OK);
     548             : 
     549          16 :         if (suite->suite_init) {
     550           2 :                 suite->suite_init_err = suite->suite_init(suite);
     551           2 :                 if (suite->suite_init_err) {
     552           0 :                         kunit_err(suite, KUNIT_SUBTEST_INDENT
     553             :                                   "# failed to initialize (%d)", suite->suite_init_err);
     554           0 :                         goto suite_end;
     555             :                 }
     556             :         }
     557             : 
     558          16 :         kunit_print_suite_start(suite);
     559             : 
     560         165 :         kunit_suite_for_each_test_case(suite, test_case) {
     561         149 :                 struct kunit test = { .param_value = NULL, .param_index = 0 };
     562         149 :                 struct kunit_result_stats param_stats = { 0 };
     563         149 :                 test_case->status = KUNIT_SKIPPED;
     564             : 
     565         298 :                 kunit_init_test(&test, test_case->name, test_case->log);
     566             : 
     567         149 :                 if (!test_case->generate_params) {
     568             :                         /* Non-parameterised test. */
     569         119 :                         kunit_run_case_catch_errors(suite, test_case, &test);
     570         119 :                         kunit_update_stats(&param_stats, test.status);
     571             :                 } else {
     572             :                         /* Get initial param. */
     573          30 :                         param_desc[0] = '\0';
     574          30 :                         test.param_value = test_case->generate_params(NULL, param_desc);
     575          30 :                         kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
     576             :                                   "KTAP version 1\n");
     577          30 :                         kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
     578             :                                   "# Subtest: %s", test_case->name);
     579             : 
     580         308 :                         while (test.param_value) {
     581         248 :                                 kunit_run_case_catch_errors(suite, test_case, &test);
     582             : 
     583         248 :                                 if (param_desc[0] == '\0') {
     584           0 :                                         snprintf(param_desc, sizeof(param_desc),
     585             :                                                  "param-%d", test.param_index);
     586             :                                 }
     587             : 
     588         744 :                                 kunit_log(KERN_INFO, &test,
     589             :                                           KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT
     590             :                                           "%s %d %s",
     591             :                                           kunit_status_to_ok_not_ok(test.status),
     592             :                                           test.param_index + 1, param_desc);
     593             : 
     594             :                                 /* Get next param. */
     595         248 :                                 param_desc[0] = '\0';
     596         248 :                                 test.param_value = test_case->generate_params(test.param_value, param_desc);
     597         248 :                                 test.param_index++;
     598             : 
     599         248 :                                 kunit_update_stats(&param_stats, test.status);
     600             :                         }
     601             :                 }
     602             : 
     603             : 
     604         149 :                 kunit_print_test_stats(&test, param_stats);
     605             : 
     606         298 :                 kunit_print_ok_not_ok(&test, true, test_case->status,
     607         149 :                                       kunit_test_case_num(suite, test_case),
     608             :                                       test_case->name,
     609             :                                       test.status_comment);
     610             : 
     611         298 :                 kunit_update_stats(&suite_stats, test_case->status);
     612         149 :                 kunit_accumulate_stats(&total_stats, param_stats);
     613             :         }
     614             : 
     615          16 :         if (suite->suite_exit)
     616           0 :                 suite->suite_exit(suite);
     617             : 
     618          16 :         kunit_print_suite_stats(suite, suite_stats, total_stats);
     619             : suite_end:
     620          16 :         kunit_print_suite_end(suite);
     621             : 
     622          16 :         return 0;
     623             : }
     624             : EXPORT_SYMBOL_GPL(kunit_run_tests);
     625             : 
     626             : static void kunit_init_suite(struct kunit_suite *suite)
     627             : {
     628          16 :         kunit_debugfs_create_suite(suite);
     629          16 :         suite->status_comment[0] = '\0';
     630          16 :         suite->suite_init_err = 0;
     631             : }
     632             : 
     633           1 : bool kunit_enabled(void)
     634             : {
     635           2 :         return enable_param;
     636             : }
     637             : 
     638           1 : int __kunit_test_suites_init(struct kunit_suite * const * const suites, int num_suites)
     639             : {
     640             :         unsigned int i;
     641             : 
     642           1 :         if (!kunit_enabled() && num_suites > 0) {
     643           0 :                 pr_info("kunit: disabled\n");
     644           0 :                 return 0;
     645             :         }
     646             : 
     647           1 :         static_branch_inc(&kunit_running);
     648             : 
     649          17 :         for (i = 0; i < num_suites; i++) {
     650          16 :                 kunit_init_suite(suites[i]);
     651          16 :                 kunit_run_tests(suites[i]);
     652             :         }
     653             : 
     654           1 :         static_branch_dec(&kunit_running);
     655           1 :         return 0;
     656             : }
     657             : EXPORT_SYMBOL_GPL(__kunit_test_suites_init);
     658             : 
     659             : static void kunit_exit_suite(struct kunit_suite *suite)
     660             : {
     661             :         kunit_debugfs_destroy_suite(suite);
     662             : }
     663             : 
     664           0 : void __kunit_test_suites_exit(struct kunit_suite **suites, int num_suites)
     665             : {
     666             :         unsigned int i;
     667             : 
     668           0 :         if (!kunit_enabled())
     669             :                 return;
     670             : 
     671             :         for (i = 0; i < num_suites; i++)
     672             :                 kunit_exit_suite(suites[i]);
     673             : 
     674           0 :         kunit_suite_counter = 1;
     675             : }
     676             : EXPORT_SYMBOL_GPL(__kunit_test_suites_exit);
     677             : 
     678             : #ifdef CONFIG_MODULES
     679             : static void kunit_module_init(struct module *mod)
     680             : {
     681             :         __kunit_test_suites_init(mod->kunit_suites, mod->num_kunit_suites);
     682             : }
     683             : 
     684             : static void kunit_module_exit(struct module *mod)
     685             : {
     686             :         __kunit_test_suites_exit(mod->kunit_suites, mod->num_kunit_suites);
     687             : }
     688             : 
     689             : static int kunit_module_notify(struct notifier_block *nb, unsigned long val,
     690             :                                void *data)
     691             : {
     692             :         struct module *mod = data;
     693             : 
     694             :         switch (val) {
     695             :         case MODULE_STATE_LIVE:
     696             :                 kunit_module_init(mod);
     697             :                 break;
     698             :         case MODULE_STATE_GOING:
     699             :                 kunit_module_exit(mod);
     700             :                 break;
     701             :         case MODULE_STATE_COMING:
     702             :         case MODULE_STATE_UNFORMED:
     703             :                 break;
     704             :         }
     705             : 
     706             :         return 0;
     707             : }
     708             : 
     709             : static struct notifier_block kunit_mod_nb = {
     710             :         .notifier_call = kunit_module_notify,
     711             :         .priority = 0,
     712             : };
     713             : #endif
     714             : 
     715             : struct kunit_kmalloc_array_params {
     716             :         size_t n;
     717             :         size_t size;
     718             :         gfp_t gfp;
     719             : };
     720             : 
     721         349 : static int kunit_kmalloc_array_init(struct kunit_resource *res, void *context)
     722             : {
     723         349 :         struct kunit_kmalloc_array_params *params = context;
     724             : 
     725         349 :         res->data = kmalloc_array(params->n, params->size, params->gfp);
     726         349 :         if (!res->data)
     727             :                 return -ENOMEM;
     728             : 
     729         349 :         return 0;
     730             : }
     731             : 
     732         349 : static void kunit_kmalloc_array_free(struct kunit_resource *res)
     733             : {
     734         349 :         kfree(res->data);
     735         349 : }
     736             : 
     737         349 : void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t gfp)
     738             : {
     739         349 :         struct kunit_kmalloc_array_params params = {
     740             :                 .size = size,
     741             :                 .n = n,
     742             :                 .gfp = gfp
     743             :         };
     744             : 
     745         349 :         return kunit_alloc_resource(test,
     746             :                                     kunit_kmalloc_array_init,
     747             :                                     kunit_kmalloc_array_free,
     748             :                                     gfp,
     749             :                                     &params);
     750             : }
     751             : EXPORT_SYMBOL_GPL(kunit_kmalloc_array);
     752             : 
     753           0 : static inline bool kunit_kfree_match(struct kunit *test,
     754             :                                      struct kunit_resource *res, void *match_data)
     755             : {
     756             :         /* Only match resources allocated with kunit_kmalloc() and friends. */
     757           0 :         return res->free == kunit_kmalloc_array_free && res->data == match_data;
     758             : }
     759             : 
     760           0 : void kunit_kfree(struct kunit *test, const void *ptr)
     761             : {
     762           0 :         if (!ptr)
     763             :                 return;
     764             : 
     765           0 :         if (kunit_destroy_resource(test, kunit_kfree_match, (void *)ptr))
     766           0 :                 KUNIT_FAIL(test, "kunit_kfree: %px already freed or not allocated by kunit", ptr);
     767             : }
     768             : EXPORT_SYMBOL_GPL(kunit_kfree);
     769             : 
     770         367 : void kunit_cleanup(struct kunit *test)
     771             : {
     772             :         struct kunit_resource *res;
     773             :         unsigned long flags;
     774             : 
     775             :         /*
     776             :          * test->resources is a stack - each allocation must be freed in the
     777             :          * reverse order from which it was added since one resource may depend
     778             :          * on another for its entire lifetime.
     779             :          * Also, we cannot use the normal list_for_each constructs, even the
     780             :          * safe ones because *arbitrary* nodes may be deleted when
     781             :          * kunit_resource_free is called; the list_for_each_safe variants only
     782             :          * protect against the current node being deleted, not the next.
     783             :          */
     784             :         while (true) {
     785        1065 :                 spin_lock_irqsave(&test->lock, flags);
     786        1432 :                 if (list_empty(&test->resources)) {
     787         734 :                         spin_unlock_irqrestore(&test->lock, flags);
     788             :                         break;
     789             :                 }
     790         349 :                 res = list_last_entry(&test->resources,
     791             :                                       struct kunit_resource,
     792             :                                       node);
     793             :                 /*
     794             :                  * Need to unlock here as a resource may remove another
     795             :                  * resource, and this can't happen if the test->lock
     796             :                  * is held.
     797             :                  */
     798         698 :                 spin_unlock_irqrestore(&test->lock, flags);
     799         349 :                 kunit_remove_resource(test, res);
     800             :         }
     801         367 :         current->kunit_test = NULL;
     802         367 : }
     803             : EXPORT_SYMBOL_GPL(kunit_cleanup);
     804             : 
     805           1 : static int __init kunit_init(void)
     806             : {
     807             :         /* Install the KUnit hook functions. */
     808             :         kunit_install_hooks();
     809             : 
     810             :         kunit_debugfs_init();
     811             : #ifdef CONFIG_MODULES
     812             :         return register_module_notifier(&kunit_mod_nb);
     813             : #else
     814           1 :         return 0;
     815             : #endif
     816             : }
     817             : late_initcall(kunit_init);
     818             : 
     819           0 : static void __exit kunit_exit(void)
     820             : {
     821           0 :         memset(&kunit_hooks, 0, sizeof(kunit_hooks));
     822             : #ifdef CONFIG_MODULES
     823             :         unregister_module_notifier(&kunit_mod_nb);
     824             : #endif
     825             :         kunit_debugfs_cleanup();
     826           0 : }
     827             : module_exit(kunit_exit);
     828             : 
     829             : MODULE_LICENSE("GPL v2");

Generated by: LCOV version 1.14