Linux Kernel Selftest development
 help / color / mirror / Atom feed
From: benjamin@sipsolutions.net
To: linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com
Cc: Johannes Berg <johannes@sipsolutions.net>,
	Benjamin Berg <benjamin.berg@intel.com>
Subject: [PATCH 2/3] kunit: add ability to register a simple cleanup function
Date: Wed, 29 Mar 2023 19:23:10 +0200	[thread overview]
Message-ID: <20230329172311.71861-2-benjamin@sipsolutions.net> (raw)
In-Reply-To: <20230329172311.71861-1-benjamin@sipsolutions.net>

From: Benjamin Berg <benjamin.berg@intel.com>

This is useful to e.g. automatically free resources at the end of the
test, without having to deal with kunit resource objects directly.

The whole point of doing this is that the callback is guaranteed to
happen in case the test aborts (due to an assertion). As such, use
assertions internally rather than requiring further error checking by
the API user.

Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
---
 include/kunit/test.h | 20 ++++++++++++++++++++
 lib/kunit/test.c     | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+)

diff --git a/include/kunit/test.h b/include/kunit/test.h
index 519b90261c72..ab1dacf1c9f4 100644
--- a/include/kunit/test.h
+++ b/include/kunit/test.h
@@ -373,6 +373,26 @@ 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);
 }
 
+typedef void (*kunit_cleanup_t)(const void *);
+
+/**
+ * kunit_add_cleanup() - Add post-test cleanup action.
+ * @test: The test case to which the resource belongs.
+ * @cleanup_func: function to call at end of test.
+ * @data: data to pass to @free_func.
+ * @internal_gfp: gfp to use for internal allocations, if unsure, use GFP_KERNEL
+ *
+ * This adds a cleanup action to be executed after the test completes.
+ * Internally this is handled using a *test managed resource*.
+ *
+ * This function will abort the test on failure.
+ *
+ * Note: KUnit needs to allocate memory for a kunit_resource object. You must
+ * specify an @internal_gfp that is compatible with the current context.
+ */
+void kunit_add_cleanup(struct kunit *test, kunit_cleanup_t cleanup_func,
+		       const void *data, gfp_t internal_gfp);
+
 void kunit_cleanup(struct kunit *test);
 
 void __printf(2, 3) kunit_log_append(char *log, const char *fmt, ...);
diff --git a/lib/kunit/test.c b/lib/kunit/test.c
index c9e15bb60058..72d956dfc324 100644
--- a/lib/kunit/test.c
+++ b/lib/kunit/test.c
@@ -719,6 +719,43 @@ void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t gfp)
 }
 EXPORT_SYMBOL_GPL(kunit_kmalloc_array);
 
+struct kunit_auto_cleanup {
+	struct kunit_resource resource;
+	kunit_cleanup_t cleanup_func;
+};
+
+static void kunit_auto_cleanup_free(struct kunit_resource *res)
+{
+	struct kunit_auto_cleanup *cleanup;
+
+	cleanup = container_of(res, struct kunit_auto_cleanup, resource);
+
+	cleanup->cleanup_func(cleanup->resource.data);
+}
+
+void kunit_add_cleanup(struct kunit *test, kunit_cleanup_t cleanup_func,
+		       const void *data, gfp_t internal_gfp)
+{
+	struct kunit_auto_cleanup *res;
+
+	KUNIT_ASSERT_NOT_NULL_MSG(test, cleanup_func,
+				  "Cleanup function must not be NULL");
+
+	res = kzalloc(sizeof(*res), internal_gfp);
+	if (!res) {
+		cleanup_func(data);
+		KUNIT_ASSERT_FAILURE(test, "Could not allocate resource for cleanup");
+	}
+
+	res->cleanup_func = cleanup_func;
+	res->resource.should_kfree = true;
+
+	/* Cannot fail as init is NULL */
+	__kunit_add_resource(test, NULL, kunit_auto_cleanup_free,
+			     &res->resource, (void *)data);
+}
+EXPORT_SYMBOL_GPL(kunit_add_cleanup);
+
 static inline bool kunit_kfree_match(struct kunit *test,
 				     struct kunit_resource *res, void *match_data)
 {
-- 
2.39.2


  reply	other threads:[~2023-03-29 17:23 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-29 17:23 [PATCH 1/3] kunit: add parameter generation macro using description from array benjamin
2023-03-29 17:23 ` benjamin [this message]
2023-03-30  6:17   ` [PATCH 2/3] kunit: add ability to register a simple cleanup function David Gow
2023-03-30  7:14     ` Benjamin Berg
2023-04-11 15:28   ` kernel test robot
2023-03-29 17:23 ` [PATCH 3/3] kunit: add a convenience allocation wrapper for SKBs benjamin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230329172311.71861-2-benjamin@sipsolutions.net \
    --to=benjamin@sipsolutions.net \
    --cc=benjamin.berg@intel.com \
    --cc=johannes@sipsolutions.net \
    --cc=kunit-dev@googlegroups.com \
    --cc=linux-kselftest@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox