^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * An API to allow a function, that may fail, to be executed, and recover in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * controlled manner.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2019, Google LLC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Brendan Higgins <brendanhiggins@google.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #ifndef _KUNIT_TRY_CATCH_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define _KUNIT_TRY_CATCH_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) typedef void (*kunit_try_catch_func_t)(void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) struct completion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct kunit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * struct kunit_try_catch - provides a generic way to run code which might fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * @test: The test case that is currently being executed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * @try_completion: Completion that the control thread waits on while test runs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * @try_result: Contains any errno obtained while running test case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * @try: The function, the test case, to attempt to run.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * @catch: The function called if @try bails out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * @context: used to pass user data to the try and catch functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * kunit_try_catch provides a generic, architecture independent way to execute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * an arbitrary function of type kunit_try_catch_func_t which may bail out by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * calling kunit_try_catch_throw(). If kunit_try_catch_throw() is called, @try
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * is stopped at the site of invocation and @catch is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * struct kunit_try_catch provides a generic interface for the functionality
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * needed to implement kunit->abort() which in turn is needed for implementing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * assertions. Assertions allow stating a precondition for a test simplifying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * how test cases are written and presented.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * Assertions are like expectations, except they abort (call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * kunit_try_catch_throw()) when the specified condition is not met. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * useful when you look at a test case as a logical statement about some piece
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * of code, where assertions are the premises for the test case, and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * conclusion is a set of predicates, rather expectations, that must all be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * true. If your premises are violated, it does not makes sense to continue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct kunit_try_catch {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* private: internal use only. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct kunit *test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct completion *try_completion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int try_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) kunit_try_catch_func_t try;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) kunit_try_catch_func_t catch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) void *context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) void __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static inline int kunit_try_catch_get_result(struct kunit_try_catch *try_catch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return try_catch->try_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #endif /* _KUNIT_TRY_CATCH_H */