/* SPDX-License-Identifier: GPL-2.0 */ /* * Base unit test (KUnit) API. * * Copyright (C) 2018, Google LLC. * Author: Brendan Higgins */ #ifndef _TEST_TEST_H #define _TEST_TEST_H #include #include #include #include #include #include #include #include #include /** * struct KUNIT_RESOURCE_T - represents a *test managed resource* * @allocation: for the user to store arbitrary data. * @free: a user supplied function to free the resource. Populated by * test_alloc_resource(). * * Represents a *test managed resource*, a resource which will automatically be * cleaned up at the end of a test case. * * Example: * * .. code-block:: c * * struct test_kmalloc_params { * size_t size; * gfp_t gfp; * }; * * static int test_kmalloc_init(struct KUNIT_RESOURCE_T *res, void *context) * { * struct test_kmalloc_params *params = context; * res->allocation = kmalloc(params->size, params->gfp); * * if (!res->allocation) * return -ENOMEM; * * return 0; * } * * static void test_kmalloc_free(struct KUNIT_RESOURCE_T *res) * { * kfree(res->allocation); * } * * void *test_kmalloc(struct KUNIT_T *test, size_t size, gfp_t gfp) * { * struct test_kmalloc_params params; * struct KUNIT_RESOURCE_T *res; * * params.size = size; * params.gfp = gfp; * * // TODO(felixguo@google.com): The & gets interpreted via * // Kerneldoc but we don't want that. * res = test_alloc_resource(test, test_kmalloc_init, * test_kmalloc_free, & params); * if (res) * return res->allocation; * else * return NULL; * } */ struct KUNIT_RESOURCE_T { void *allocation; void (*free)(struct KUNIT_RESOURCE_T *res); /* private: internal use only. */ struct list_head node; }; struct KUNIT_T; /** * struct KUNIT_CASE_T - represents an individual test case. * @run_case: the function representing the actual test case. * @name: the name of the test case. * * A test case is a function with the signature, ``void (*)(struct KUNIT_T *)`` * that makes expectations and assertions (see EXPECT_TRUE() and ASSERT_TRUE()) * about code under test. Each test case is associated with a * &struct KUNIT_SUITE_T and will be run after the module's init function and * followed by the module's exit function. * * A test case should be static and should only be created with the TEST_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_T *test) * { * EXPECT_EQ(test, 1, add(1, 0)); * EXPECT_EQ(test, 2, add(1, 1)); * EXPECT_EQ(test, 0, add(-1, 1)); * EXPECT_EQ(test, INT_MAX, add(0, INT_MAX)); * EXPECT_EQ(test, -1, add(INT_MAX, INT_MIN)); * } * * static struct KUNIT_CASE_T example_test_cases[] = { * TEST_CASE(add_test_basic), * {}, * }; * */ struct KUNIT_CASE_T { void (*run_case)(struct KUNIT_T *test); const char name[256]; /* private: internal use only. */ bool success; }; /** * TEST_CASE - A helper for creating a &struct KUNIT_CASE_T * @test_name: a reference to a test case function. * * Takes a symbol for a function representing a test case and creates a &struct * test_case object from it. See the documentation for &struct KUNIT_CASE_T for an * example on how to use it. */ #define TEST_CASE(test_name) { .run_case = test_name, .name = #test_name } /** * struct KUNIT_SUITE_T - describes a related collection of &struct KUNIT_CASE_T s. * @name: the name of the test. Purely informational. * @init: called before every test case. * @exit: called after every test case. * @test_cases: a null terminated array of test cases. * * A test_module is a collection of related &struct KUNIT_CASE_T 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 frameworks like JUnit or Googletest. * * Every &struct KUNIT_CASE_T must be associated with a test_module for KUnit to * run it. */ struct KUNIT_SUITE_T { const char name[256]; int (*init)(struct KUNIT_T *test); void (*exit)(struct KUNIT_T *test); struct KUNIT_CASE_T *test_cases; }; struct test_initcall { struct list_head node; int (*init)(struct test_initcall *this, struct KUNIT_T *test); void (*exit)(struct test_initcall *this); }; struct test_post_condition { struct list_head node; void (*validate)(struct test_post_condition *condition); }; /** * struct KUNIT_T - represents a running instance of a test. * @priv: for user to store arbitrary data. Commonly used to pass data created * in the init function (see &struct KUNIT_SUITE_T). * * Used to store information about the current context under which the test is * running. Most of this data is private and should only be accessed indirectly * via public functions; the one exception is @priv which can be used by the * test writer to store arbitrary data. */ struct KUNIT_T { void *priv; /* private: internal use only. */ spinlock_t lock; /* Guards all mutable test state. */ struct list_head resources; struct list_head post_conditions; const char *name; bool death_test; bool success; void (*vprintk)(const struct KUNIT_T *test, const char *level, struct va_format *vaf); void (*fail)(struct KUNIT_T *test, struct test_stream *stream); void (*abort)(struct KUNIT_T *test); struct test_try_catch try_catch; }; static inline void test_set_death_test(struct KUNIT_T *test, bool death_test) { unsigned long flags; spin_lock_irqsave(&test->lock, flags); test->death_test = death_test; spin_unlock_irqrestore(&test->lock, flags); } int test_init_test(struct KUNIT_T *test, const char *name); int test_run_tests(struct KUNIT_SUITE_T *module); extern int register_kunit_notifier(struct notifier_block *nb); extern int unregister_kunit_notifier(struct notifier_block *nb); #if IS_ENABLED(CONFIG_SEC_KUNIT) int test_executor_init(void); #else static inline int test_executor_init(void) { return 0; } #endif void test_install_initcall(struct test_initcall *initcall); #define test_pure_initcall(fn) postcore_initcall(fn) #define test_register_initcall(initcall) \ static int register_test_initcall_##initcall(void) \ { \ test_install_initcall(&initcall); \ \ return 0; \ } \ test_pure_initcall(register_test_initcall_##initcall) /** * module_test() - used to register a &struct KUNIT_SUITE_T with KUnit. * @module: a statically allocated &struct KUNIT_SUITE_T. * * Registers @module with the test framework. See &struct KUNIT_SUITE_T for more * information. * Hardcoding the alignment to 8 was chosen as the most likely to remain * between the compiler laying out the test module pointers in the custom * section and the linker script placing the custom section in the output * binary. There must be no gap between the section start and the first * (test_module *) entry nor between any (test_module *) entries because * the test executor views the .test_modules section as an array of * (test_module *) starting at __test_modules_start. */ #define module_test(module) \ static struct KUNIT_SUITE_T *__test_module_##module __used \ __aligned(8) __attribute__((__section__(".test_modules"))) = \ &module /** * kunit_notifier_chain_init() - initialize kunit notifier for module built * test which is included in target ko module. * @module: a statically allocated &struct test_module. * * For the on device KUnit testing, the module built KUuit tests are not * triggered by test_run_tests(). because it is assigned in the .test_modules * section. So trigger the test_module directly with notifier call chain after * the test.ko module loaded. */ #define kunit_notifier_chain_init(module) \ extern struct test_module module; \ static int kunit_run_notify_##module(struct notifier_block *self, \ unsigned long event, void *data) \ { \ if (test_run_tests(&module)) { \ printk("kunit error: %s\n", module.name); \ return NOTIFY_BAD; \ } \ return NOTIFY_OK; \ } \ static struct notifier_block callchain_notifier_##module = { \ .notifier_call = kunit_run_notify_##module, \ }; #define kunit_notifier_chain_register(module) \ register_kunit_notifier(&callchain_notifier_##module); #define kunit_notifier_chain_unregister(module) \ unregister_kunit_notifier(&callchain_notifier_##module); /** * module_test_for_module() - used to register a &struct test_module for the * KUnit test which is module built independently. * @module: a statically allocated &struct test_module. * * Use module_test_for_module() instead of module_test() for the independent * module built test. */ #if IS_ENABLED(CONFIG_UML) #define module_test_for_module(module) module_test(module) #else #define module_test_for_module(module) \ kunit_notifier_chain_init(module); \ static int __init kunit_test_suites_init(void) \ { \ printk("register module %s to kunit_notifier\n", module.name); \ kunit_notifier_chain_register(module); \ return 0; \ } \ module_init(kunit_test_suites_init); \ static void __exit kunit_test_suites_exit(void) \ { \ printk("unregister module %s to kunit_notifier\n", module.name);\ kunit_notifier_chain_unregister(module); \ } \ module_exit(kunit_test_suites_exit); \ MODULE_LICENSE("GPL"); #endif /* CONFIG_UML */ /** * test_alloc_resource() - Allocates a *test managed resource*. * @test: The test context object. * @init: a user supplied function to initialize the resource. * @free: a user supplied function to free the resource. * @context: for the user to pass in arbitrary data. * * Allocates a *test managed resource*, a resource which will automatically be * cleaned up at the end of a test case. See &struct KUNIT_RESOURCE_T for an * example. */ struct KUNIT_RESOURCE_T *test_alloc_resource(struct KUNIT_T *test, int (*init)(struct KUNIT_RESOURCE_T *, void *), void (*free)(struct KUNIT_RESOURCE_T *), void *context); void test_free_resource(struct KUNIT_T *test, struct KUNIT_RESOURCE_T *res); /** * test_kmalloc() - Just like kmalloc() except the allocation is *test managed*. * @test: The test context object. * @size: The size in bytes of the desired memory. * @gfp: flags passed to underlying kmalloc(). * * Just like `kmalloc(...)`, except the allocation is managed by the test case * and is automatically cleaned up after the test case concludes. See &struct * KUNIT_RESOURCE_T for more information. */ void *test_kmalloc(struct KUNIT_T *test, size_t size, gfp_t gfp); /** * test_kzalloc() - Just like test_kmalloc(), but zeroes the allocation. * @test: The test context object. * @size: The size in bytes of the desired memory. * @gfp: flags passed to underlying kmalloc(). * * See kzalloc() and test_kmalloc() for more information. */ static inline void *test_kzalloc(struct KUNIT_T *test, size_t size, gfp_t gfp) { return test_kmalloc(test, size, gfp | __GFP_ZERO); } void test_cleanup(struct KUNIT_T *test); void test_printk(const char *level, const struct KUNIT_T *test, const char *fmt, ...); /** * test_info() - Prints an INFO level message associated with the current test. * @test: The test context object. * @fmt: A printk() style format string. * * Prints an info level message associated with the test module being run. Takes * a variable number of format parameters just like printk(). */ #define test_info(test, fmt, ...) \ test_printk(KERN_INFO, test, fmt, ##__VA_ARGS__) /** * test_warn() - Prints a WARN level message associated with the current test. * @test: The test context object. * @fmt: A printk() style format string. * * See test_info(). */ #define test_warn(test, fmt, ...) \ test_printk(KERN_WARNING, test, fmt, ##__VA_ARGS__) /** * test_err() - Prints an ERROR level message associated with the current test. * @test: The test context object. * @fmt: A printk() style format string. * * See test_info(). */ #define test_err(test, fmt, ...) \ test_printk(KERN_ERR, test, fmt, ##__VA_ARGS__) static inline struct test_stream *test_expect_start(struct KUNIT_T *test, const char *file, const char *line) { struct test_stream *stream = test_new_stream(test); stream->add(stream, "EXPECTATION FAILED at %s:%s\n\t", file, line); return stream; } static inline void test_expect_end(struct KUNIT_T *test, bool success, struct test_stream *stream) { if (!success) test->fail(test, stream); else stream->clear(stream); } #define EXPECT_START(test) \ test_expect_start(test, __FILE__, __stringify(__LINE__)) #define EXPECT_END(test, success, stream) test_expect_end(test, success, stream) #define EXPECT(test, success, message) do {\ struct test_stream *__stream = EXPECT_START(test); \ \ __stream->add(__stream, message); \ EXPECT_END(test, success, __stream); \ } while (0) /** * SUCCEED() - A no-op expectation. Only exists for code clarity. * @test: The test context object. * * The opposite of FAIL(), it is an expectation that cannot fail. In other * words, it does nothing and only exists for code clarity. See EXPECT_TRUE() * for more information. */ #define SUCCEED(test) do {} while (0) /** * FAIL() - Always causes a test to fail when evaluated. * @test: The test context object. * @message: an informational message to be printed when the assertion is made. * * The opposite of SUCCEED(), it is an expectation that always fails. In other * words, it always results in a failed expectation, and consequently always * causes the test case to fail when evaluated. See EXPECT_TRUE() for more * information. */ #define FAIL(test, message) EXPECT(test, false, message) /** * EXPECT_TRUE() - Causes a test failure when the given expression is not true. * @test: The test context object. * @condition: an arbitrary boolean expression. The test fails when this does * not evaluate to true. * * This and expectations of the form `EXPECT_*` will cause the test case to fail * when the specified condition is not met; however, it will not prevent the * test case from continuing to run; this is otherwise known as an *expectation * failure*. */ #define EXPECT_TRUE(test, condition) \ EXPECT(test, (condition), \ "Expected " #condition " is true, but is false.") /** * EXPECT_FALSE() - Causes a test failure when the expression is not false. * @test: The test context object. * @condition: an arbitrary boolean expression. The test fails when this does * not evaluate to false. * * Sets an expectation that @condition evaluates to false. See EXPECT_TRUE() for * more information. */ #define EXPECT_FALSE(test, condition) \ EXPECT(test, !(condition), \ "Expected " #condition " is false, but is true.") /** * EXPECT_NOT_NULL() - Causes a test failure when @expression is NULL. * @test: The test context object. * @expression: an arbitrary pointer expression. The test fails when this * evaluates to NULL. * * Sets an expectation that @expression does not evaluate to NULL. Similar to * EXPECT_TRUE() but supposed to be used with pointer expressions. */ #define EXPECT_NOT_NULL(test, expression) \ EXPECT(test, (expression), \ "Expected " #expression " is not NULL, but is NULL.") /** * EXPECT_NULL() - Causes a test failure when @expression is not NULL. * @test: The test context object. * @expression: an arbitrary pointer expression. The test fails when this does * not evaluate to NULL. * * Sets an expectation that @expression evaluates to NULL. Similar to * EXPECT_FALSE() but supposed to be used with pointer expressions. */ #define EXPECT_NULL(test, expression) \ EXPECT(test, !(expression), \ "Expected " #expression " is NULL, but is not NULL.") /** * EXPECT_SUCCESS() - Causes a test failure if @expression does not evaluate * to 0. * @test: The test context object. * @expression: an arbitrary expression evaluating to an int error code. The * test fails when this does not evaluate to 0. * * Sets an expectation that @expression evaluates to 0. Implementation assumes * that error codes are represented as negative values and if expression * evaluates to a negative value failure message will contain a mnemonic * representation of the error code (for example, for -1 it will contain EPERM). */ #define EXPECT_SUCCESS(test, expression) do { \ struct test_stream *__stream = EXPECT_START(test); \ typeof(expression) __result = (expression); \ char buf[64]; \ \ if (__result != 0) \ __stream->add(__stream, \ "Expected " #expression " is not error, " \ "but is: %s.", \ strerror_r(-__result, buf, sizeof(buf))); \ EXPECT_END(test, __result == 0, __stream); \ } while (0) /** * EXPECT_ERROR() - Causes a test failure when @expression does not evaluate to @errno. * @test: The test context object. * @expression: an arbitrary expression evaluating to an int error code. The * test fails when this does not evaluate to @errno. * @errno: expected error value, error values are expected to be negative. * * Sets an expectation that @expression evaluates to @errno, so as opposed to * EXPECT_SUCCESS it verifies that @expression evaluates to an error. */ #define EXPECT_ERROR(test, expression, errno) do { \ struct test_stream *__stream = EXPECT_START(test); \ typeof(expression) __result = (expression); \ char buf1[64]; \ char buf2[64]; \ \ if (__result != errno) \ __stream->add(__stream, \ "Expected " #expression " is %s, but is: %s.", \ strerror_r(-errno, buf1, sizeof(buf1)), \ strerror_r(-__result, buf2, sizeof(buf2))); \ EXPECT_END(test, __result == errno, __stream); \ } while (0) static inline void test_expect_binary(struct KUNIT_T *test, long long left, const char *left_name, long long right, const char *right_name, bool compare_result, const char *compare_name, const char *file, const char *line) { struct test_stream *stream = test_expect_start(test, file, line); stream->add(stream, "Expected %s %s %s, but\n", left_name, compare_name, right_name); stream->add(stream, "\t\t%s == %lld\n", left_name, left); stream->add(stream, "\t\t%s == %lld", right_name, right); test_expect_end(test, compare_result, stream); } /* * A factory macro for defining the expectations for the basic comparisons * defined for the built in types. * * Unfortunately, there is no common type that all types can be promoted to for * which all the binary operators behave the same way as for the actual types * (for example, there is no type that long long and unsigned long long can * both be cast to where the comparison result is preserved for all values). So * the best we can do is do the comparison in the original types and then coerce * everything to long long for printing; this way, the comparison behaves * correctly and the printed out value usually makes sense without * interpretation, but can always be interpretted to figure out the actual * value. */ #define EXPECT_BINARY(test, left, condition, right) do { \ typeof(left) __left = (left); \ typeof(right) __right = (right); \ test_expect_binary(test, \ (long long) __left, #left, \ (long long) __right, #right, \ __left condition __right, #condition, \ __FILE__, __stringify(__LINE__)); \ } while (0) /** * EXPECT_EQ() - Sets an expectation that @left and @right are equal. * @test: The test context object. * @left: an arbitrary expression that evaluates to a primitive C type. * @right: an arbitrary expression that evaluates to a primitive C type. * * Sets an expectation that the values that @left and @right evaluate to are * equal. This is semantically equivalent to EXPECT_TRUE(@test, (@left) == * (@right)). See EXPECT_TRUE() for more information. */ #define EXPECT_EQ(test, left, right) EXPECT_BINARY(test, left, ==, right) /** * EXPECT_NE() - An expectation that @left and @right are not equal. * @test: The test context object. * @left: an arbitrary expression that evaluates to a primitive C type. * @right: an arbitrary expression that evaluates to a primitive C type. * * Sets an expectation that the values that @left and @right evaluate to are not * equal. This is semantically equivalent to EXPECT_TRUE(@test, (@left) != * (@right)). See EXPECT_TRUE() for more information. */ #define EXPECT_NE(test, left, right) EXPECT_BINARY(test, left, !=, right) /** * EXPECT_LT() - An expectation that @left is less than @right. * @test: The test context object. * @left: an arbitrary expression that evaluates to a primitive C type. * @right: an arbitrary expression that evaluates to a primitive C type. * * Sets an expectation that the value that @left evaluates to is less than the * value that @right evaluates to. This is semantically equivalent to * EXPECT_TRUE(@test, (@left) < (@right)). See EXPECT_TRUE() for more * information. */ #define EXPECT_LT(test, left, right) EXPECT_BINARY(test, left, <, right) /** * EXPECT_LE() - An expectation that @left is less than or equal to @right. * @test: The test context object. * @left: an arbitrary expression that evaluates to a primitive C type. * @right: an arbitrary expression that evaluates to a primitive C type. * * Sets an expectation that the value that @left evaluates to is less than or * equal to the value that @right evaluates to. Semantically this is equivalent * to EXPECT_TRUE(@test, (@left) <= (@right)). See EXPECT_TRUE() for more * information. */ #define EXPECT_LE(test, left, right) EXPECT_BINARY(test, left, <=, right) /** * EXPECT_GT() - An expectation that @left is greater than @right. * @test: The test context object. * @left: an arbitrary expression that evaluates to a primitive C type. * @right: an arbitrary expression that evaluates to a primitive C type. * * Sets an expectation that the value that @left evaluates to is greater than * the value that @right evaluates to. This is semantically equivalent to * EXPECT_TRUE(@test, (@left) > (@right)). See EXPECT_TRUE() for more * information. */ #define EXPECT_GT(test, left, right) EXPECT_BINARY(test, left, >, right) /** * EXPECT_GE() - An expectation that @left is greater than or equal to @right. * @test: The test context object. * @left: an arbitrary expression that evaluates to a primitive C type. * @right: an arbitrary expression that evaluates to a primitive C type. * * Sets an expectation that the value that @left evaluates to is greater than * the value that @right evaluates to. This is semantically equivalent to * EXPECT_TRUE(@test, (@left) >= (@right)). See EXPECT_TRUE() for more * information. */ #define EXPECT_GE(test, left, right) EXPECT_BINARY(test, left, >=, right) /** * EXPECT_STREQ() - An expectation that strings @left and @right are equal. * @test: The test context object. * @left: an arbitrary expression that evaluates to a null terminated string. * @right: an arbitrary expression that evaluates to a null terminated string. * * Sets an expectation that the values that @left and @right evaluate to are * equal. This is semantically equivalent to * EXPECT_TRUE(@test, !strcmp((@left), (@right))). See EXPECT_TRUE() for more * information. */ #define EXPECT_STREQ(test, left, right) do { \ struct test_stream *__stream = EXPECT_START(test); \ typeof(left) __left = (left); \ typeof(right) __right = (right); \ \ __stream->add(__stream, "Expected " #left " == " #right ", but\n"); \ __stream->add(__stream, "\t\t%s == %s\n", #left, __left); \ __stream->add(__stream, "\t\t%s == %s\n", #right, __right); \ \ EXPECT_END(test, !strcmp(left, right), __stream); \ } while (0) /** * EXPECT_NOT_ERR_OR_NULL() - An expectation that @ptr is not null and not err. * @test: The test context object. * @ptr: an arbitrary pointer. * * Sets an expectation that the value that @ptr evaluates to is not null and * not an errno stored in a pointer. This is semantically equivalent to * EXPECT_TRUE(@test, !IS_ERR_OR_NULL(@ptr)). See EXPECT_TRUE() for more * information. */ #define EXPECT_NOT_ERR_OR_NULL(test, ptr) do { \ struct test_stream *__stream = EXPECT_START(test); \ typeof(ptr) __ptr = (ptr); \ char buf[64]; \ \ if (!__ptr) \ __stream->add(__stream, \ "Expected " #ptr " is not null, but is."); \ if (IS_ERR(__ptr)) \ __stream->add(__stream, \ "Expected " #ptr " is not error, but is: %s", \ strerror_r(-PTR_ERR(__ptr), buf, sizeof(buf))); \ \ EXPECT_END(test, !IS_ERR_OR_NULL(__ptr), __stream); \ } while (0) static inline struct test_stream *test_assert_start(struct KUNIT_T *test, const char *file, const char *line) { struct test_stream *stream = test_new_stream(test); stream->add(stream, "ASSERTION FAILED at %s:%s\n\t", file, line); return stream; } static inline void test_assert_end(struct KUNIT_T *test, bool success, struct test_stream *stream) { if (!success) { test->fail(test, stream); test->abort(test); } else { stream->clear(stream); } } #define ASSERT_START(test) \ test_assert_start(test, __FILE__, __stringify(__LINE__)) #define ASSERT_END(test, success, stream) test_assert_end(test, success, stream) #define __ASSERT(test, success, message) do { \ struct test_stream *__stream = ASSERT_START(test); \ \ __stream->add(__stream, message); \ ASSERT_END(test, success, __stream); \ } while (0) #define ASSERT_FAILURE(test, message) __ASSERT(test, false, message) /** * ASSERT_TRUE() - Causes an assertion failure when the expression is not true. * @test: The test context object. * @condition: an arbitrary boolean expression. The test fails and aborts when * this does not evaluate to true. * * This and assertions of the form `ASSERT_*` will cause the test case to fail * *and immediately abort* when the specified condition is not met. Unlike an * expectation failure, it will prevent the test case from continuing to run; * this is otherwise known as an *assertion failure*. */ #define ASSERT_TRUE(test, condition) \ __ASSERT(test, (condition), \ "Asserted " #condition " is true, but is false.") /** * ASSERT_FALSE() - Sets an assertion that @condition is false. * @test: The test context object. * @condition: an arbitrary boolean expression. * * Sets an assertion that the value that @condition evaluates to is false. This * is the same as EXPECT_FALSE(), except it causes an assertion failure (see * ASSERT_TRUE()) when the assertion is not met. */ #define ASSERT_FALSE(test, condition) \ __ASSERT(test, !(condition), \ "Asserted " #condition " is false, but is true.") /** * ASSERT_NOT_NULL() - Asserts that @expression does not evaluate to NULL. * @test: The test context object. * @expression: an arbitrary pointer expression. The test fails when this * evaluates to NULL. * * Asserts that @expression does not evaluate to NULL, see EXPECT_NOT_NULL(). */ #define ASSERT_NOT_NULL(test, expression) \ __ASSERT(test, (expression), \ "Expected " #expression " is not NULL, but is NULL.") /** * ASSERT_NULL() - Asserts that @expression evaluates to NULL. * @test: The test context object. * @expression: an arbitrary pointer expression. The test fails when this does * not evaluate to NULL. * * Asserts that @expression evaluates to NULL, see EXPECT_NULL(). */ #define ASSERT_NULL(test, expression) \ __ASSERT(test, !(expression), \ "Expected " #expression " is NULL, but is not NULL.") /** * ASSERT_SUCCESS() - Asserts that @expression is 0. * @test: The test context object. * @expression: an arbitrary expression evaluating to an int error code. * * Asserts that @expression evaluates to 0. It's the same as EXPECT_SUCCESS. */ #define ASSERT_SUCCESS(test, expression) do { \ struct test_stream *__stream = ASSERT_START(test); \ typeof(expression) __result = (expression); \ char buf[64]; \ \ if (__result != 0) \ __stream->add(__stream, \ "Asserted " #expression " is not error, " \ "but is: %s.", \ strerror_r(-__result, buf, sizeof(buf))); \ ASSERT_END(test, __result == 0, __stream); \ } while (0) /** * ASSERT_ERROR() - Causes a test failure when @expression does not evaluate to * @errno. * @test: The test context object. * @expression: an arbitrary expression evaluating to an int error code. The * test fails when this does not evaluate to @errno. * @errno: expected error value, error values are expected to be negative. * * Asserts that @expression evaluates to @errno, similar to EXPECT_ERROR. */ #define ASSERT_ERROR(test, expression, errno) do { \ struct test_stream *__stream = ASSERT_START(test); \ typeof(expression) __result = (expression); \ char buf1[64]; \ char buf2[64]; \ \ if (__result != errno) \ __stream->add(__stream, \ "Expected " #expression " is %s, but is: %s.", \ strerror_r(-errno, buf1, sizeof(buf1)), \ strerror_r(-__result, buf2, sizeof(buf2))); \ ASSERT_END(test, __result == errno, __stream); \ } while (0) static inline void test_assert_binary(struct KUNIT_T *test, long long left, const char *left_name, long long right, const char *right_name, bool compare_result, const char *compare_name, const char *file, const char *line) { struct test_stream *stream = test_assert_start(test, file, line); stream->add(stream, "Asserted %s %s %s, but\n", left_name, compare_name, right_name); stream->add(stream, "\t\t%s == %lld\n", left_name, left); stream->add(stream, "\t\t%s == %lld", right_name, right); test_assert_end(test, compare_result, stream); } /* * A factory macro for defining the expectations for the basic comparisons * defined for the built in types. * * Unfortunately, there is no common type that all types can be promoted to for * which all the binary operators behave the same way as for the actual types * (for example, there is no type that long long and unsigned long long can * both be cast to where the comparison result is preserved for all values). So * the best we can do is do the comparison in the original types and then coerce * everything to long long for printing; this way, the comparison behaves * correctly and the printed out value usually makes sense without * interpretation, but can always be interpretted to figure out the actual * value. */ #define ASSERT_BINARY(test, left, condition, right) do { \ typeof(left) __left = (left); \ typeof(right) __right = (right); \ test_assert_binary(test, \ (long long) __left, #left, \ (long long) __right, #right, \ __left condition __right, #condition, \ __FILE__, __stringify(__LINE__)); \ } while (0) /** * ASSERT_EQ() - Sets an assertion that @left and @right are equal. * @test: The test context object. * @left: an arbitrary expression that evaluates to a primitive C type. * @right: an arbitrary expression that evaluates to a primitive C type. * * Sets an assertion that the values that @left and @right evaluate to are * equal. This is the same as EXPECT_EQ(), except it causes an assertion failure * (see ASSERT_TRUE()) when the assertion is not met. */ #define ASSERT_EQ(test, left, right) ASSERT_BINARY(test, left, ==, right) /** * ASSERT_NE() - An assertion that @left and @right are not equal. * @test: The test context object. * @left: an arbitrary expression that evaluates to a primitive C type. * @right: an arbitrary expression that evaluates to a primitive C type. * * Sets an assertion that the values that @left and @right evaluate to are not * equal. This is the same as EXPECT_NE(), except it causes an assertion failure * (see ASSERT_TRUE()) when the assertion is not met. */ #define ASSERT_NE(test, left, right) ASSERT_BINARY(test, left, !=, right) /** * ASSERT_LT() - An assertion that @left is less than @right. * @test: The test context object. * @left: an arbitrary expression that evaluates to a primitive C type. * @right: an arbitrary expression that evaluates to a primitive C type. * * Sets an assertion that the value that @left evaluates to is less than the * value that @right evaluates to. This is the same as EXPECT_LT(), except it * causes an assertion failure (see ASSERT_TRUE()) when the assertion is not * met. */ #define ASSERT_LT(test, left, right) ASSERT_BINARY(test, left, <, right) /** * ASSERT_LE() - An assertion that @left is less than or equal to @right. * @test: The test context object. * @left: an arbitrary expression that evaluates to a primitive C type. * @right: an arbitrary expression that evaluates to a primitive C type. * * Sets an assertion that the value that @left evaluates to is less than or * equal to the value that @right evaluates to. This is the same as * EXPECT_LE(), except it causes an assertion failure (see ASSERT_TRUE()) when * the assertion is not met. */ #define ASSERT_LE(test, left, right) ASSERT_BINARY(test, left, <=, right) /** * ASSERT_GT() - An assertion that @left is greater than @right. * @test: The test context object. * @left: an arbitrary expression that evaluates to a primitive C type. * @right: an arbitrary expression that evaluates to a primitive C type. * * Sets an assertion that the value that @left evaluates to is greater than the * value that @right evaluates to. This is the same as EXPECT_GT(), except it * causes an assertion failure (see ASSERT_TRUE()) when the assertion is not * met. */ #define ASSERT_GT(test, left, right) ASSERT_BINARY(test, left, >, right) /** * ASSERT_GE() - An assertion that @left is greater than or equal to @right. * @test: The test context object. * @left: an arbitrary expression that evaluates to a primitive C type. * @right: an arbitrary expression that evaluates to a primitive C type. * * Sets an assertion that the value that @left evaluates to is greater than the * value that @right evaluates to. This is the same as EXPECT_GE(), except it * causes an assertion failure (see ASSERT_TRUE()) when the assertion is not * met. */ #define ASSERT_GE(test, left, right) ASSERT_BINARY(test, left, >=, right) /** * ASSERT_STREQ() - An assertion that strings @left and @right are equal. * @test: The test context object. * @left: an arbitrary expression that evaluates to a null terminated string. * @right: an arbitrary expression that evaluates to a null terminated string. * * Sets an assertion that the values that @left and @right evaluate to are * equal. This is the same as EXPECT_STREQ(), except it causes an assertion * failure (see ASSERT_TRUE()) when the assertion is not met. */ #define ASSERT_STREQ(test, left, right) do { \ struct test_stream *__stream = ASSERT_START(test); \ typeof(left) __left = (left); \ typeof(right) __right = (right); \ \ __stream->add(__stream, "Asserted " #left " == " #right ", but\n"); \ __stream->add(__stream, "\t\t%s == %s\n", #left, __left); \ __stream->add(__stream, "\t\t%s == %s\n", #right, __right); \ \ ASSERT_END(test, !strcmp(left, right), __stream); \ } while (0) /** * ASSERT_NOT_ERR_OR_NULL() - An assertion that @ptr is not null and not err. * @test: The test context object. * @ptr: an arbitrary pointer. * * Sets an assertion that the value that @ptr evaluates to is not null and not * an errno stored in a pointer. This is the same as EXPECT_NOT_ERR_OR_NULL(), * except it causes an assertion failure (see ASSERT_TRUE()) when the assertion * is not met. */ #define ASSERT_NOT_ERR_OR_NULL(test, ptr) do { \ struct test_stream *__stream = ASSERT_START(test); \ typeof(ptr) __ptr = (ptr); \ char buf[64]; \ \ if (!__ptr) \ __stream->add(__stream, \ "Asserted " #ptr " is not null, but is."); \ if (IS_ERR(__ptr)) \ __stream->add(__stream, \ "Asserted " #ptr " is not error, but is: %s", \ strerror_r(-PTR_ERR(__ptr), buf, sizeof(buf))); \ \ ASSERT_END(test, !IS_ERR_OR_NULL(__ptr), __stream); \ } while (0) /** * ASSERT_SIGSEGV() - An assertion that @expr will cause a segfault. * @test: The test context object. * @expr: an arbitrary block of code. * * Sets an assertion that @expr, when evaluated, will cause a segfault. * Currently this assertion is only really useful for testing the KUnit * framework, as a segmentation fault in normal kernel code is always incorrect. * However, the plan is to replace this assertion with an arbitrary death * assertion similar to * https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#death-tests * which will probably be massaged to make sense in the context of the kernel * (maybe assert that a panic occurred, or that BUG() was called). * * NOTE: no code after this assertion will ever be executed. */ #define ASSERT_SIGSEGV(test, expr) do { \ test->death_test = true; \ expr; \ test->death_test = false; \ ASSERT_FAILURE(test, \ "Asserted that " #expr " would cause death, but did not.");\ } while (0) #endif /* _TEST_TEST_H */