kunit: Add kunit_add_action() to defer a call until test exit
Many uses of the KUnit resource system are intended to simply defer calling a function until the test exits (be it due to success or failure). The existing kunit_alloc_resource() function is often used for this, but was awkward to use (requiring passing NULL init functions, etc), and returned a resource without incrementing its reference count, which -- while okay for this use-case -- could cause problems in others. Instead, introduce a simple kunit_add_action() API: a simple function (returning nothing, accepting a single void* argument) can be scheduled to be called when the test exits. Deferred actions are called in the opposite order to that which they were registered. This mimics the devres API, devm_add_action(), and also provides kunit_remove_action(), to cancel a deferred action, and kunit_release_action() to trigger one early. This is implemented as a resource under the hood, so the ordering between resource cleanup and deferred functions is maintained. Reviewed-by: Benjamin Berg <benjamin.berg@intel.com> Reviewed-by: Maxime Ripard <maxime@cerno.tech> Tested-by: Maxime Ripard <maxime@cerno.tech> Signed-off-by: David Gow <davidgow@google.com> Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
This commit is contained in:
@@ -387,4 +387,96 @@ static inline int kunit_destroy_named_resource(struct kunit *test,
|
||||
*/
|
||||
void kunit_remove_resource(struct kunit *test, struct kunit_resource *res);
|
||||
|
||||
/* A 'deferred action' function to be used with kunit_add_action. */
|
||||
typedef void (kunit_action_t)(void *);
|
||||
|
||||
/**
|
||||
* kunit_add_action() - Call a function when the test ends.
|
||||
* @test: Test case to associate the action with.
|
||||
* @func: The function to run on test exit
|
||||
* @ctx: Data passed into @func
|
||||
*
|
||||
* Defer the execution of a function until the test exits, either normally or
|
||||
* due to a failure. @ctx is passed as additional context. All functions
|
||||
* registered with kunit_add_action() will execute in the opposite order to that
|
||||
* they were registered in.
|
||||
*
|
||||
* This is useful for cleaning up allocated memory and resources, as these
|
||||
* functions are called even if the test aborts early due to, e.g., a failed
|
||||
* assertion.
|
||||
*
|
||||
* See also: devm_add_action() for the devres equivalent.
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, an error if the action could not be deferred.
|
||||
*/
|
||||
int kunit_add_action(struct kunit *test, kunit_action_t *action, void *ctx);
|
||||
|
||||
/**
|
||||
* kunit_add_action_or_reset() - Call a function when the test ends.
|
||||
* @test: Test case to associate the action with.
|
||||
* @func: The function to run on test exit
|
||||
* @ctx: Data passed into @func
|
||||
*
|
||||
* Defer the execution of a function until the test exits, either normally or
|
||||
* due to a failure. @ctx is passed as additional context. All functions
|
||||
* registered with kunit_add_action() will execute in the opposite order to that
|
||||
* they were registered in.
|
||||
*
|
||||
* This is useful for cleaning up allocated memory and resources, as these
|
||||
* functions are called even if the test aborts early due to, e.g., a failed
|
||||
* assertion.
|
||||
*
|
||||
* If the action cannot be created (e.g., due to the system being out of memory),
|
||||
* then action(ctx) will be called immediately, and an error will be returned.
|
||||
*
|
||||
* See also: devm_add_action_or_reset() for the devres equivalent.
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, an error if the action could not be deferred.
|
||||
*/
|
||||
int kunit_add_action_or_reset(struct kunit *test, kunit_action_t *action,
|
||||
void *ctx);
|
||||
|
||||
/**
|
||||
* kunit_remove_action() - Cancel a matching deferred action.
|
||||
* @test: Test case the action is associated with.
|
||||
* @func: The deferred function to cancel.
|
||||
* @ctx: The context passed to the deferred function to trigger.
|
||||
*
|
||||
* Prevent an action deferred via kunit_add_action() from executing when the
|
||||
* test terminates.
|
||||
*
|
||||
* If the function/context pair was deferred multiple times, only the most
|
||||
* recent one will be cancelled.
|
||||
*
|
||||
* See also: devm_remove_action() for the devres equivalent.
|
||||
*/
|
||||
void kunit_remove_action(struct kunit *test,
|
||||
kunit_action_t *action,
|
||||
void *ctx);
|
||||
|
||||
/**
|
||||
* kunit_release_action() - Run a matching action call immediately.
|
||||
* @test: Test case the action is associated with.
|
||||
* @func: The deferred function to trigger.
|
||||
* @ctx: The context passed to the deferred function to trigger.
|
||||
*
|
||||
* Execute a function deferred via kunit_add_action()) immediately, rather than
|
||||
* when the test ends.
|
||||
*
|
||||
* If the function/context pair was deferred multiple times, it will only be
|
||||
* executed once here. The most recent deferral will no longer execute when
|
||||
* the test ends.
|
||||
*
|
||||
* kunit_release_action(test, func, ctx);
|
||||
* is equivalent to
|
||||
* func(ctx);
|
||||
* kunit_remove_action(test, func, ctx);
|
||||
*
|
||||
* See also: devm_release_action() for the devres equivalent.
|
||||
*/
|
||||
void kunit_release_action(struct kunit *test,
|
||||
kunit_action_t *action,
|
||||
void *ctx);
|
||||
#endif /* _KUNIT_RESOURCE_H */
|
||||
|
||||
Reference in New Issue
Block a user