On Mon, 14 Aug 2023 at 21:23, Richard Fitzgerald rf@opensource.cirrus.com wrote:
string_stream_resource_free_test() allocates a resource-managed string_stream and tests that raw_free_string_stream() is called when the test resources are cleaned up.
string_stream_init_test() is extended to test allocating a string_stream that is not resource-managed.
Signed-off-by: Richard Fitzgerald rf@opensource.cirrus.com
Glad to see this tested. It's nice to see the static_stub being useful here, too.
Reviewed-by: David Gow davidgow@google.com
Cheers, -- David
lib/kunit/string-stream-test.c | 117 ++++++++++++++++++++++++++++++++- lib/kunit/string-stream.c | 3 + 2 files changed, 119 insertions(+), 1 deletion(-)
diff --git a/lib/kunit/string-stream-test.c b/lib/kunit/string-stream-test.c index 437aa4b3179d..05bfade2bd8a 100644 --- a/lib/kunit/string-stream-test.c +++ b/lib/kunit/string-stream-test.c @@ -6,16 +6,27 @@
- Author: Brendan Higgins brendanhiggins@google.com
*/
+#include <kunit/static_stub.h> #include <kunit/test.h> #include <linux/slab.h>
#include "string-stream.h"
+struct string_stream_test_priv {
struct string_stream *raw_stream;
/* For testing resource-managed free */
struct string_stream *freed_stream;
bool stream_free_again;
+};
/* string_stream object is initialized correctly. */ static void string_stream_init_test(struct kunit *test) {
struct string_stream_test_priv *priv = test->priv; struct string_stream *stream;
/* Resource-managed initialization */ stream = alloc_string_stream(test, GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
@@ -26,6 +37,86 @@ static void string_stream_init_test(struct kunit *test) KUNIT_EXPECT_FALSE(test, stream->append_newlines);
KUNIT_EXPECT_TRUE(test, string_stream_is_empty(stream));
free_string_stream(test, stream);
/*
* Raw initialization. This allocation is not resource-managed
* so store it in priv->raw_stream to be cleaned up by the
* exit function.
*/
priv->raw_stream = raw_alloc_string_stream(GFP_KERNEL);
stream = priv->raw_stream;
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
KUNIT_EXPECT_EQ(test, stream->length, 0);
KUNIT_EXPECT_TRUE(test, list_empty(&stream->fragments));
KUNIT_EXPECT_PTR_EQ(test, stream->test, NULL);
KUNIT_EXPECT_EQ(test, stream->gfp, GFP_KERNEL);
Again, this will probably annoy sparse, so expect an email from ktr. We'll look into how to fix this in either KUnit or sparse separately.
KUNIT_EXPECT_FALSE(test, stream->append_newlines);
KUNIT_EXPECT_TRUE(test, string_stream_is_empty(stream));
+}
+static void string_stream_raw_free_string_stream_stub(struct string_stream *stream) +{
struct kunit *fake_test = kunit_get_current_test();
struct string_stream_test_priv *priv = fake_test->priv;
if (priv->freed_stream)
priv->stream_free_again = true;
priv->freed_stream = stream;
/*
* Avoid calling deactivate_static_stub() or changing
* current->kunit_test during cleanup. Leave the stream to
* be freed during the test exit.
*/
+}
+/* string_stream object is freed when test is cleaned up. */ +static void string_stream_resource_free_test(struct kunit *test) +{
struct string_stream_test_priv *priv = test->priv;
struct kunit *fake_test;
struct string_stream *stream;
fake_test = kunit_kzalloc(test, sizeof(*fake_test), GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fake_test);
kunit_init_test(fake_test, "string_stream_fake_test", NULL);
fake_test->priv = priv;
/*
* Activate stub before creating string_stream so the
* string_stream will be cleaned up first.
*/
priv->freed_stream = NULL;
priv->stream_free_again = false;
kunit_activate_static_stub(fake_test,
raw_free_string_stream,
string_stream_raw_free_string_stream_stub);
stream = alloc_string_stream(fake_test, GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
/*
* Ensure the stream is freed when this test terminates.
*/
priv->raw_stream = stream;
/* Set current->kunit_test to fake_test so the static stub will be called. */
current->kunit_test = fake_test;
/* Cleanup test - the stub function should be called */
kunit_cleanup(fake_test);
/* Set current->kunit_test back to current test. */
current->kunit_test = test;
KUNIT_EXPECT_PTR_EQ(test, priv->freed_stream, stream);
KUNIT_EXPECT_FALSE(test, priv->stream_free_again);
}
/* @@ -279,8 +370,30 @@ static void string_stream_auto_newline_test(struct kunit *test) "One\nTwo\nThree\nFour\nFive\nSix\nSeven\n\nEight\n"); }
+static int string_stream_test_init(struct kunit *test) +{
struct string_stream_test_priv *priv;
priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
test->priv = priv;
return 0;
+}
+static void string_stream_test_exit(struct kunit *test) +{
struct string_stream_test_priv *priv = test->priv;
if (priv && priv->raw_stream)
raw_free_string_stream(priv->raw_stream);
+}
static struct kunit_case string_stream_test_cases[] = { KUNIT_CASE(string_stream_init_test),
KUNIT_CASE(string_stream_resource_free_test), KUNIT_CASE(string_stream_line_add_test), KUNIT_CASE(string_stream_variable_length_line_test), KUNIT_CASE(string_stream_append_test),
@@ -292,6 +405,8 @@ static struct kunit_case string_stream_test_cases[] = {
static struct kunit_suite string_stream_test_suite = { .name = "string-stream-test",
.test_cases = string_stream_test_cases
.test_cases = string_stream_test_cases,
.init = string_stream_test_init,
.exit = string_stream_test_exit,
}; kunit_test_suites(&string_stream_test_suite); diff --git a/lib/kunit/string-stream.c b/lib/kunit/string-stream.c index 06104a729b45..1b55ac1be2e5 100644 --- a/lib/kunit/string-stream.c +++ b/lib/kunit/string-stream.c @@ -6,6 +6,7 @@
- Author: Brendan Higgins brendanhiggins@google.com
*/
+#include <kunit/static_stub.h> #include <kunit/test.h> #include <linux/list.h> #include <linux/slab.h> @@ -167,6 +168,8 @@ bool string_stream_is_empty(struct string_stream *stream)
void raw_free_string_stream(struct string_stream *stream) {
KUNIT_STATIC_STUB_REDIRECT(raw_free_string_stream, stream);
string_stream_clear(stream); kfree(stream);
}
2.30.2