/* SPDX-License-Identifier: GPL-2.0 */
/*
* Base unit test (KUnit) API.
*
* Copyright (C) 2019, Google LLC.
* Author: Brendan Higgins <brendanhiggins@google.com>
*/
#ifndef _KUNIT_TEST_H
#define _KUNIT_TEST_H
#include <kunit/assert.h>
#include <kunit/try-catch.h>
#include <linux/compiler.h>
#include <linux/container_of.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kconfig.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/types.h>
#include <asm/rwonce.h>
struct kunit;
/* Size of log associated with test. */
#define KUNIT_LOG_SIZE 512
/* Maximum size of parameter description string. */
#define KUNIT_PARAM_DESC_SIZE 128
/* Maximum size of a status comment. */
#define KUNIT_STATUS_COMMENT_SIZE 256
/*
* TAP specifies subtest stream indentation of 4 spaces, 8 spaces for a
* sub-subtest. See the "Subtests" section in
* https://node-tap.org/tap-protocol/
*/
#define KUNIT_SUBTEST_INDENT " "
#define KUNIT_SUBSUBTEST_INDENT " "
/**
* enum kunit_status - Type of result for a test or test suite
* @KUNIT_SUCCESS: Denotes the test suite has not failed nor been skipped
* @KUNIT_FAILURE: Denotes the test has failed.
* @KUNIT_SKIPPED: Denotes the test has been skipped.
*/
enum kunit_status {
KUNIT_SUCCESS,
KUNIT_FAILURE,
KUNIT_SKIPPED,
};
/**
* struct kunit_case - represents an individual test case.
*
* @run_case: the function representing the actual test case.
* @name: the name of the test case.
* @generate_params: the generator function for parameterized tests.
*
* A test case is a function with the signature,
* ``void (*)(struct kunit *)``
* that makes expectations and assertions (see KUNIT_EXPECT_TRUE() and
* KUNIT_ASSERT_TRUE()) about code under test. Each test case is associated
* with a &struct kunit_suite and will be run after the suite's init
* function and followed by the suite's exit function.
*
* A test case should be static and should only be created with the
* KUNIT_CASE() macro; additionally, every array of test cases should be
* terminated with an empty test case.
*
* Example:
*
* .. code-block:: c
*
* void add_test_basic(struct kunit *test)
* {
* KUNIT_EXPECT_EQ(test, 1, add(1, 0));
* KUNIT_EXPECT_EQ(test, 2, add(1, 1));
* KUNIT_EXPECT_EQ(test, 0, add(-1, 1));
* KUNIT_EXPECT_EQ(test, INT_MAX, add(0, INT_MAX));
* KUNIT_EXPECT_EQ(test, -1, add(INT_MAX, INT_MIN));
* }
*
* static struct kunit_case example_test_cases[] = {
* KUNIT_CASE(add_test_basic),
* {}
* };
*
*/
struct kunit_case {
void (*run_case)(struct kunit *test);
const char *name;
const void* (*generate_params)(const void *prev, char *desc);
/* private: internal use only. */
enum kunit_status status;
char *log;
};
static inline char *kunit_status_to_ok_not_ok(enum kunit_status status)
{
switch (status) {
case KUNIT_SKIPPED:
case KUNIT_SUCCESS:
return "ok";
case KUNIT_FAILURE:
return "not ok";
}
return "invalid";
}
/**
* KUNIT_CASE - A helper for creating a &struct kunit_case
*
* @test_name: a reference to a test case function.
*
* Takes a symbol for a function representing a test case and creates a
* &struct kunit_case object from it. See the documentation for
* &struct kunit_case for an example on how to use it.
*/
#define KUNIT_CASE(test_name) { .run_case = test_name, .name = #test_name }
/**
* KUNIT_CASE_PARAM - A helper for creation a parameterized &struct kunit_case
*
* @test_name: a reference to a test case function.
* @gen_params: a reference to a parameter generator function.
*
* The generator function::
*
* const void* gen_params(const void *prev, char *desc)
*
* is used to lazily generate a series of arbitrarily typed values that fit into
* a void*. The argument @prev is the previously returned value, which should be
* used to derive the next value; @prev is set to NULL on the initial generator
* call. When no more values are available, the generator must return NULL.
* Optionally write a string into @desc (size of KUNIT_PARAM_DESC_SIZE)
* describing the parameter.
*/
#define KUNIT_CASE_PARAM(test_name, gen_params) \
{ .run_case = test_name, .name = #test_name, \
.generate_params = gen_params }
/**
* struct kunit_suite - describes a related collection of &struct kunit_case
*
* @name: the name of the test. Purely informational.
* @suite_init: called once per test suite before the test cases.
* @suite_exit: called once per test suite after all test cases.
* @init: called before every test case.
* @exit: called after every test case.
* @test_cases: a null terminated array of test cases.
*
* A kunit_suite is a collection of related &struct kunit_case s, such that
* @init is called before every test case and @exit is called after every
* test case, similar to the notion of a *test fixture* or a *test class*
* in other unit testing framewo