diff options
Diffstat (limited to 'include/kunit/test.h')
-rw-r--r-- | include/kunit/test.h | 185 |
1 files changed, 168 insertions, 17 deletions
diff --git a/include/kunit/test.h b/include/kunit/test.h index 61637ef32302..0ffb97c78566 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -28,6 +28,7 @@ #include <linux/types.h> #include <asm/rwonce.h> +#include <asm/sections.h> /* Static key: true if any KUnit tests are currently running */ DECLARE_STATIC_KEY_FALSE(kunit_running); @@ -301,6 +302,8 @@ struct kunit { struct list_head resources; /* Protected by lock. */ char status_comment[KUNIT_STATUS_COMMENT_SIZE]; + /* Saves the last seen test. Useful to help with faults. */ + struct kunit_loc last_seen; }; static inline void kunit_set_failure(struct kunit *test) @@ -309,6 +312,7 @@ static inline void kunit_set_failure(struct kunit *test) } bool kunit_enabled(void); +bool kunit_autorun(void); const char *kunit_action(void); const char *kunit_filter_glob(void); char *kunit_filter(void); @@ -331,7 +335,8 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set, int *err); void kunit_free_suite_set(struct kunit_suite_set suite_set); -int __kunit_test_suites_init(struct kunit_suite * const * const suites, int num_suites); +int __kunit_test_suites_init(struct kunit_suite * const * const suites, int num_suites, + bool run_tests); void __kunit_test_suites_exit(struct kunit_suite **suites, int num_suites); @@ -478,14 +483,79 @@ static inline void *kunit_kcalloc(struct kunit *test, size_t n, size_t size, gfp return kunit_kmalloc_array(test, n, size, gfp | __GFP_ZERO); } + +/** + * kunit_kfree_const() - conditionally free test managed memory + * @test: The test context object. + * @x: pointer to the memory + * + * Calls kunit_kfree() only if @x is not in .rodata section. + * See kunit_kstrdup_const() for more information. + */ +void kunit_kfree_const(struct kunit *test, const void *x); + +/** + * kunit_kstrdup() - Duplicates a string into a test managed allocation. + * + * @test: The test context object. + * @str: The NULL-terminated string to duplicate. + * @gfp: flags passed to underlying kmalloc(). + * + * See kstrdup() and kunit_kmalloc_array() for more information. + */ +static inline char *kunit_kstrdup(struct kunit *test, const char *str, gfp_t gfp) +{ + size_t len; + char *buf; + + if (!str) + return NULL; + + len = strlen(str) + 1; + buf = kunit_kmalloc(test, len, gfp); + if (buf) + memcpy(buf, str, len); + return buf; +} + +/** + * kunit_kstrdup_const() - Conditionally duplicates a string into a test managed allocation. + * + * @test: The test context object. + * @str: The NULL-terminated string to duplicate. + * @gfp: flags passed to underlying kmalloc(). + * + * Calls kunit_kstrdup() only if @str is not in the rodata section. Must be freed with + * kunit_kfree_const() -- not kunit_kfree(). + * See kstrdup_const() and kunit_kmalloc_array() for more information. + */ +const char *kunit_kstrdup_const(struct kunit *test, const char *str, gfp_t gfp); + +/** + * kunit_vm_mmap() - Allocate KUnit-tracked vm_mmap() area + * @test: The test context object. + * @file: struct file pointer to map from, if any + * @addr: desired address, if any + * @len: how many bytes to allocate + * @prot: mmap PROT_* bits + * @flag: mmap flags + * @offset: offset into @file to start mapping from. + * + * See vm_mmap() for more information. + */ +unsigned long kunit_vm_mmap(struct kunit *test, struct file *file, + unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flag, + unsigned long offset); + void kunit_cleanup(struct kunit *test); void __printf(2, 3) kunit_log_append(struct string_stream *log, const char *fmt, ...); /** - * kunit_mark_skipped() - Marks @test_or_suite as skipped + * kunit_mark_skipped() - Marks @test as skipped * - * @test_or_suite: The test context object. + * @test: The test context object. * @fmt: A printk() style format string. * * Marks the test as skipped. @fmt is given output as the test status @@ -493,18 +563,18 @@ void __printf(2, 3) kunit_log_append(struct string_stream *log, const char *fmt, * * Test execution continues after kunit_mark_skipped() is called. */ -#define kunit_mark_skipped(test_or_suite, fmt, ...) \ +#define kunit_mark_skipped(test, fmt, ...) \ do { \ - WRITE_ONCE((test_or_suite)->status, KUNIT_SKIPPED); \ - scnprintf((test_or_suite)->status_comment, \ + WRITE_ONCE((test)->status, KUNIT_SKIPPED); \ + scnprintf((test)->status_comment, \ KUNIT_STATUS_COMMENT_SIZE, \ fmt, ##__VA_ARGS__); \ } while (0) /** - * kunit_skip() - Marks @test_or_suite as skipped + * kunit_skip() - Marks @test as skipped * - * @test_or_suite: The test context object. + * @test: The test context object. * @fmt: A printk() style format string. * * Skips the test. @fmt is given output as the test status @@ -512,10 +582,10 @@ void __printf(2, 3) kunit_log_append(struct string_stream *log, const char *fmt, * * Test execution is halted after kunit_skip() is called. */ -#define kunit_skip(test_or_suite, fmt, ...) \ +#define kunit_skip(test, fmt, ...) \ do { \ - kunit_mark_skipped((test_or_suite), fmt, ##__VA_ARGS__);\ - kunit_try_catch_throw(&((test_or_suite)->try_catch)); \ + kunit_mark_skipped((test), fmt, ##__VA_ARGS__); \ + kunit_try_catch_throw(&((test)->try_catch)); \ } while (0) /* @@ -567,6 +637,15 @@ void __printf(2, 3) kunit_log_append(struct string_stream *log, const char *fmt, #define kunit_err(test, fmt, ...) \ kunit_printk(KERN_ERR, test, fmt, ##__VA_ARGS__) +/* + * Must be called at the beginning of each KUNIT_*_ASSERTION(). + * Cf. KUNIT_CURRENT_LOC. + */ +#define _KUNIT_SAVE_LOC(test) do { \ + WRITE_ONCE(test->last_seen.file, __FILE__); \ + WRITE_ONCE(test->last_seen.line, __LINE__); \ +} while (0) + /** * KUNIT_SUCCEED() - A no-op expectation. Only exists for code clarity. * @test: The test context object. @@ -575,7 +654,7 @@ void __printf(2, 3) kunit_log_append(struct string_stream *log, const char *fmt, * words, it does nothing and only exists for code clarity. See * KUNIT_EXPECT_TRUE() for more information. */ -#define KUNIT_SUCCEED(test) do {} while (0) +#define KUNIT_SUCCEED(test) _KUNIT_SAVE_LOC(test) void __noreturn __kunit_abort(struct kunit *test); @@ -601,14 +680,16 @@ void __printf(6, 7) __kunit_do_failed_assertion(struct kunit *test, } while (0) -#define KUNIT_FAIL_ASSERTION(test, assert_type, fmt, ...) \ +#define KUNIT_FAIL_ASSERTION(test, assert_type, fmt, ...) do { \ + _KUNIT_SAVE_LOC(test); \ _KUNIT_FAILED(test, \ assert_type, \ kunit_fail_assert, \ kunit_fail_assert_format, \ {}, \ fmt, \ - ##__VA_ARGS__) + ##__VA_ARGS__); \ +} while (0) /** * KUNIT_FAIL() - Always causes a test to fail when evaluated. @@ -637,6 +718,7 @@ void __printf(6, 7) __kunit_do_failed_assertion(struct kunit *test, fmt, \ ...) \ do { \ + _KUNIT_SAVE_LOC(test); \ if (likely(!!(condition_) == !!expected_true_)) \ break; \ \ @@ -698,6 +780,7 @@ do { \ .right_text = #right, \ }; \ \ + _KUNIT_SAVE_LOC(test); \ if (likely(__left op __right)) \ break; \ \ @@ -758,6 +841,7 @@ do { \ .right_text = #right, \ }; \ \ + _KUNIT_SAVE_LOC(test); \ if (likely((__left) && (__right) && (strcmp(__left, __right) op 0))) \ break; \ \ @@ -791,6 +875,7 @@ do { \ .right_text = #right, \ }; \ \ + _KUNIT_SAVE_LOC(test); \ if (likely(__left && __right)) \ if (likely(memcmp(__left, __right, __size) op 0)) \ break; \ @@ -815,6 +900,7 @@ do { \ do { \ const typeof(ptr) __ptr = (ptr); \ \ + _KUNIT_SAVE_LOC(test); \ if (!IS_ERR_OR_NULL(__ptr)) \ break; \ \ @@ -1193,7 +1279,18 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_ASSERT_FAILURE(test, fmt, ...) \ +/** + * KUNIT_FAIL_AND_ABORT() - Always causes a test to fail and abort when evaluated. + * @test: The test context object. + * @fmt: an informational message to be printed when the assertion is made. + * @...: string format arguments. + * + * The opposite of KUNIT_SUCCEED(), it is an assertion that always fails. In + * other words, it always results in a failed assertion, and consequently + * always causes the test case to fail and abort when evaluated. + * See KUNIT_ASSERT_TRUE() for more information. + */ +#define KUNIT_FAIL_AND_ABORT(test, fmt, ...) \ KUNIT_FAIL_ASSERTION(test, KUNIT_ASSERTION, fmt, ##__VA_ARGS__) /** @@ -1420,12 +1517,12 @@ do { \ ##__VA_ARGS__) /** - * KUNIT_ASSERT_STRNEQ() - Expects that strings @left and @right are not equal. + * KUNIT_ASSERT_STRNEQ() - An assertion that strings @left and @right are not 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 + * Sets an assertion that the values that @left and @right evaluate to are * not equal. This is semantically equivalent to * KUNIT_ASSERT_TRUE(@test, strcmp((@left), (@right))). See KUNIT_ASSERT_TRUE() * for more information. @@ -1441,6 +1538,60 @@ do { \ ##__VA_ARGS__) /** + * KUNIT_ASSERT_MEMEQ() - Asserts that the first @size bytes of @left and @right are equal. + * @test: The test context object. + * @left: An arbitrary expression that evaluates to the specified size. + * @right: An arbitrary expression that evaluates to the specified size. + * @size: Number of bytes compared. + * + * Sets an assertion that the values that @left and @right evaluate to are + * equal. This is semantically equivalent to + * KUNIT_ASSERT_TRUE(@test, !memcmp((@left), (@right), (@size))). See + * KUNIT_ASSERT_TRUE() for more information. + * + * Although this assertion works for any memory block, it is not recommended + * for comparing more structured data, such as structs. This assertion is + * recommended for comparing, for example, data arrays. + */ +#define KUNIT_ASSERT_MEMEQ(test, left, right, size) \ + KUNIT_ASSERT_MEMEQ_MSG(test, left, right, size, NULL) + +#define KUNIT_ASSERT_MEMEQ_MSG(test, left, right, size, fmt, ...) \ + KUNIT_MEM_ASSERTION(test, \ + KUNIT_ASSERTION, \ + left, ==, right, \ + size, \ + fmt, \ + ##__VA_ARGS__) + +/** + * KUNIT_ASSERT_MEMNEQ() - Asserts that the first @size bytes of @left and @right are not equal. + * @test: The test context object. + * @left: An arbitrary expression that evaluates to the specified size. + * @right: An arbitrary expression that evaluates to the specified size. + * @size: Number of bytes compared. + * + * Sets an assertion that the values that @left and @right evaluate to are + * not equal. This is semantically equivalent to + * KUNIT_ASSERT_TRUE(@test, memcmp((@left), (@right), (@size))). See + * KUNIT_ASSERT_TRUE() for more information. + * + * Although this assertion works for any memory block, it is not recommended + * for comparing more structured data, such as structs. This assertion is + * recommended for comparing, for example, data arrays. + */ +#define KUNIT_ASSERT_MEMNEQ(test, left, right, size) \ + KUNIT_ASSERT_MEMNEQ_MSG(test, left, right, size, NULL) + +#define KUNIT_ASSERT_MEMNEQ_MSG(test, left, right, size, fmt, ...) \ + KUNIT_MEM_ASSERTION(test, \ + KUNIT_ASSERTION, \ + left, !=, right, \ + size, \ + fmt, \ + ##__VA_ARGS__) + +/** * KUNIT_ASSERT_NULL() - Asserts that pointers @ptr is null. * @test: The test context object. * @ptr: an arbitrary pointer. |