[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CA+GJov6u0+y-GBS4c2pvEmvUdoezMpXD-MJO3e_G90yefMV-iQ@mail.gmail.com>
Date: Fri, 21 Jun 2024 17:38:05 -0400
From: Rae Moar <rmoar@...gle.com>
To: Ivan Orlov <ivan.orlov0322@...il.com>
Cc: brendan.higgins@...ux.dev, davidgow@...gle.com,
linux-kselftest@...r.kernel.org, kunit-dev@...glegroups.com,
linux-kernel@...r.kernel.org, skhan@...uxfoundation.org
Subject: Re: [PATCH v2 5/5] kunit: Merge assertion test into kunit-test.c
On Tue, Jun 18, 2024 at 1:03 PM Ivan Orlov <ivan.orlov0322@...il.com> wrote:
>
> Since assert_test covers the part of the KUnit core (the assertion
> formatting functions), I believe it would be better to have it merged
> into kunit-test (as it is done for other tests for the KUnit core).
>
> Signed-off-by: Ivan Orlov <ivan.orlov0322@...il.com>
Hello!
This looks good to me. I don't know if it was necessary to move the
assert tests but I definitely see the reasoning. Happy with this as it
is. There are a few checkpatch warnings I have mentioned below but I
think the use case makes it necessary.
Reviewed-by: Rae Moar <rmoar@...gle.com>
Thanks!
-Rae
> ---
> V1 -> V2:
> - Update considering the changes in the previous patch (use
> kunit_assert_ prefixed functions)
>
> lib/kunit/Makefile | 5 -
> lib/kunit/assert_test.c | 388 ----------------------------------------
> lib/kunit/kunit-test.c | 379 ++++++++++++++++++++++++++++++++++++++-
> 3 files changed, 378 insertions(+), 394 deletions(-)
> delete mode 100644 lib/kunit/assert_test.c
>
> diff --git a/lib/kunit/Makefile b/lib/kunit/Makefile
> index 478beb536dc9..18e506b897a6 100644
> --- a/lib/kunit/Makefile
> +++ b/lib/kunit/Makefile
> @@ -21,9 +21,4 @@ obj-y += hooks.o
> obj-$(CONFIG_KUNIT_TEST) += kunit-test.o
> obj-$(CONFIG_KUNIT_STRING_STREAM_TEST) += string-stream-test.o
>
> -# string-stream-test compiles built-in only.
> -ifeq ($(CONFIG_KUNIT_TEST),y)
> -obj-$(CONFIG_KUNIT_TEST) += assert_test.o
> -endif
> -
> obj-$(CONFIG_KUNIT_EXAMPLE_TEST) += kunit-example-test.o
> diff --git a/lib/kunit/assert_test.c b/lib/kunit/assert_test.c
> deleted file mode 100644
> index 4999233180d6..000000000000
> --- a/lib/kunit/assert_test.c
> +++ /dev/null
> @@ -1,388 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-or-later
> -/*
> - * KUnit test for the assertion formatting functions.
> - * Author: Ivan Orlov <ivan.orlov0322@...il.com>
> - */
> -#include <kunit/test.h>
> -#include "string-stream.h"
> -
> -#define TEST_PTR_EXPECTED_BUF_SIZE 32
> -#define HEXDUMP_TEST_BUF_LEN 5
> -#define ASSERT_TEST_EXPECT_CONTAIN(test, str, substr) KUNIT_EXPECT_TRUE(test, strstr(str, substr))
> -#define ASSERT_TEST_EXPECT_NCONTAIN(test, str, substr) KUNIT_EXPECT_FALSE(test, strstr(str, substr))
> -
> -static void kunit_test_assert_is_literal(struct kunit *test)
> -{
> - KUNIT_EXPECT_TRUE(test, kunit_assert_is_literal("5", 5));
> - KUNIT_EXPECT_TRUE(test, kunit_assert_is_literal("0", 0));
> - KUNIT_EXPECT_TRUE(test, kunit_assert_is_literal("1234567890", 1234567890));
> - KUNIT_EXPECT_TRUE(test, kunit_assert_is_literal("-1234567890", -1234567890));
> - KUNIT_EXPECT_FALSE(test, kunit_assert_is_literal("05", 5));
> - KUNIT_EXPECT_FALSE(test, kunit_assert_is_literal("", 0));
> - KUNIT_EXPECT_FALSE(test, kunit_assert_is_literal("-0", 0));
> - KUNIT_EXPECT_FALSE(test, kunit_assert_is_literal("12#45", 1245));
> -}
> -
> -static void kunit_test_assert_is_str_literal(struct kunit *test)
> -{
> - KUNIT_EXPECT_TRUE(test, kunit_assert_is_str_literal("\"Hello, World!\"", "Hello, World!"));
> - KUNIT_EXPECT_TRUE(test, kunit_assert_is_str_literal("\"\"", ""));
> - KUNIT_EXPECT_TRUE(test, kunit_assert_is_str_literal("\"\"\"", "\""));
> - KUNIT_EXPECT_FALSE(test, kunit_assert_is_str_literal("", ""));
> - KUNIT_EXPECT_FALSE(test, kunit_assert_is_str_literal("\"", "\""));
> - KUNIT_EXPECT_FALSE(test, kunit_assert_is_str_literal("\"Abacaba", "Abacaba"));
> - KUNIT_EXPECT_FALSE(test, kunit_assert_is_str_literal("Abacaba\"", "Abacaba"));
> - KUNIT_EXPECT_FALSE(test, kunit_assert_is_str_literal("\"Abacaba\"", "\"Abacaba\""));
> -}
> -
> -KUNIT_DEFINE_ACTION_WRAPPER(kfree_wrapper, kfree, const void *);
> -
> -/* this function is used to get a "char *" string from the string stream and defer its cleanup */
> -static char *get_str_from_stream(struct kunit *test, struct string_stream *stream)
> -{
> - char *str = string_stream_get_string(stream);
> -
> - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, str);
> - kunit_add_action(test, kfree_wrapper, (void *)str);
> -
> - return str;
> -}
> -
> -static void kunit_test_assert_prologue(struct kunit *test)
> -{
> - struct string_stream *stream;
> - char *str;
> - const struct kunit_loc location = {
> - .file = "testfile.c",
> - .line = 1337,
> - };
> -
> - stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> -
> - /* Test an expectation fail prologue */
> - kunit_assert_prologue(&location, KUNIT_EXPECTATION, stream);
> - str = get_str_from_stream(test, stream);
> - ASSERT_TEST_EXPECT_CONTAIN(test, str, "EXPECTATION");
> - ASSERT_TEST_EXPECT_CONTAIN(test, str, "testfile.c");
> - ASSERT_TEST_EXPECT_CONTAIN(test, str, "1337");
> -
> - /* Test an assertion fail prologue */
> - string_stream_clear(stream);
> - kunit_assert_prologue(&location, KUNIT_ASSERTION, stream);
> - str = get_str_from_stream(test, stream);
> - ASSERT_TEST_EXPECT_CONTAIN(test, str, "ASSERTION");
> - ASSERT_TEST_EXPECT_CONTAIN(test, str, "testfile.c");
> - ASSERT_TEST_EXPECT_CONTAIN(test, str, "1337");
> -}
> -
> -/*
> - * This function accepts an arbitrary count of parameters and generates a va_format struct,
> - * which can be used to validate kunit_assert_print_msg function
> - */
> -static void verify_assert_print_msg(struct kunit *test,
> - struct string_stream *stream,
> - char *expected, const char *format, ...)
> -{
> - va_list list;
> - const struct va_format vformat = {
> - .fmt = format,
> - .va = &list,
> - };
> -
> - va_start(list, format);
> - string_stream_clear(stream);
> - kunit_assert_print_msg(&vformat, stream);
> - KUNIT_EXPECT_STREQ(test, get_str_from_stream(test, stream), expected);
> -}
> -
> -static void kunit_test_assert_print_msg(struct kunit *test)
> -{
> - struct string_stream *stream;
> -
> - stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> -
> - verify_assert_print_msg(test, stream, "\nTest", "Test");
> - verify_assert_print_msg(test, stream, "\nAbacaba -123 234", "%s %d %u",
> - "Abacaba", -123, 234U);
> - verify_assert_print_msg(test, stream, "", NULL);
> -}
> -
> -/*
> - * Further code contains the tests for different assert format functions.
> - * This helper function accepts the assert format function, executes it and
> - * validates the result string from the stream by checking that all of the
> - * substrings exist in the output.
> - */
> -static void validate_assert(assert_format_t format_func, struct kunit *test,
> - const struct kunit_assert *assert,
> - struct string_stream *stream, int num_checks, ...)
> -{
> - size_t i;
> - va_list checks;
> - char *cur_substr_exp;
> - struct va_format message = { NULL, NULL };
> -
> - va_start(checks, num_checks);
> - string_stream_clear(stream);
> - format_func(assert, &message, stream);
> -
> - for (i = 0; i < num_checks; i++) {
> - cur_substr_exp = va_arg(checks, char *);
> - ASSERT_TEST_EXPECT_CONTAIN(test, get_str_from_stream(test, stream), cur_substr_exp);
> - }
> -}
> -
> -static void kunit_test_unary_assert_format(struct kunit *test)
> -{
> - struct string_stream *stream;
> - struct kunit_assert assert = {};
> - struct kunit_unary_assert un_assert = {
> - .assert = assert,
> - .condition = "expr",
> - .expected_true = true,
> - };
> -
> - stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> -
> - validate_assert(kunit_unary_assert_format, test, &un_assert.assert,
> - stream, 2, "true", "is false");
> -
> - un_assert.expected_true = false;
> - validate_assert(kunit_unary_assert_format, test, &un_assert.assert,
> - stream, 2, "false", "is true");
> -}
> -
> -static void kunit_test_ptr_not_err_assert_format(struct kunit *test)
> -{
> - struct string_stream *stream;
> - struct kunit_assert assert = {};
> - struct kunit_ptr_not_err_assert not_err_assert = {
> - .assert = assert,
> - .text = "expr",
> - .value = NULL,
> - };
> -
> - stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> -
> - /* Value is NULL. The corresponding message should be printed out */
> - validate_assert(kunit_ptr_not_err_assert_format, test,
> - ¬_err_assert.assert,
> - stream, 1, "null");
> -
> - /* Value is not NULL, but looks like an error pointer. Error should be printed out */
> - not_err_assert.value = (void *)-12;
> - validate_assert(kunit_ptr_not_err_assert_format, test,
> - ¬_err_assert.assert, stream, 2,
> - "error", "-12");
> -}
> -
> -static void kunit_test_binary_assert_format(struct kunit *test)
> -{
> - struct string_stream *stream;
> - struct kunit_assert assert = {};
> - struct kunit_binary_assert_text text = {
> - .left_text = "1 + 2",
> - .operation = "==",
> - .right_text = "2",
> - };
> - const struct kunit_binary_assert binary_assert = {
> - .assert = assert,
> - .text = &text,
> - .left_value = 3,
> - .right_value = 2,
> - };
> -
> - stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> -
> - /*
> - * Printed values should depend on the input we provide: the left text, right text, left
> - * value and the right value.
> - */
> - validate_assert(kunit_binary_assert_format, test, &binary_assert.assert,
> - stream, 4, "1 + 2", "2", "3", "==");
> -
> - text.right_text = "4 - 2";
> - validate_assert(kunit_binary_assert_format, test, &binary_assert.assert,
> - stream, 3, "==", "1 + 2", "4 - 2");
> -
> - text.left_text = "3";
> - validate_assert(kunit_binary_assert_format, test, &binary_assert.assert,
> - stream, 4, "3", "4 - 2", "2", "==");
> -
> - text.right_text = "2";
> - validate_assert(kunit_binary_assert_format, test, &binary_assert.assert,
> - stream, 3, "3", "2", "==");
> -}
> -
> -static void kunit_test_binary_ptr_assert_format(struct kunit *test)
> -{
> - struct string_stream *stream;
> - struct kunit_assert assert = {};
> - char *addr_var_a, *addr_var_b;
> - static const void *var_a = (void *)0xDEADBEEF;
> - static const void *var_b = (void *)0xBADDCAFE;
> - struct kunit_binary_assert_text text = {
> - .left_text = "var_a",
> - .operation = "==",
> - .right_text = "var_b",
> - };
> - struct kunit_binary_ptr_assert binary_ptr_assert = {
> - .assert = assert,
> - .text = &text,
> - .left_value = var_a,
> - .right_value = var_b,
> - };
> -
> - addr_var_a = kunit_kzalloc(test, TEST_PTR_EXPECTED_BUF_SIZE, GFP_KERNEL);
> - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, addr_var_a);
> - addr_var_b = kunit_kzalloc(test, TEST_PTR_EXPECTED_BUF_SIZE, GFP_KERNEL);
> - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, addr_var_b);
> - /*
> - * Print the addresses to the buffers first.
> - * This is necessary as we may have different count of leading zeros in the pointer
> - * on different architectures.
> - */
> - snprintf(addr_var_a, TEST_PTR_EXPECTED_BUF_SIZE, "%px", var_a);
> - snprintf(addr_var_b, TEST_PTR_EXPECTED_BUF_SIZE, "%px", var_b);
> -
> - stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> - validate_assert(kunit_binary_ptr_assert_format, test, &binary_ptr_assert.assert,
> - stream, 3, addr_var_a, addr_var_b, "==");
> -}
> -
> -static void kunit_test_binary_str_assert_format(struct kunit *test)
> -{
> - struct string_stream *stream;
> - struct kunit_assert assert = {};
> - static const char *var_a = "abacaba";
> - static const char *var_b = "kernel";
> - struct kunit_binary_assert_text text = {
> - .left_text = "var_a",
> - .operation = "==",
> - .right_text = "var_b",
> - };
> - struct kunit_binary_str_assert binary_str_assert = {
> - .assert = assert,
> - .text = &text,
> - .left_value = var_a,
> - .right_value = var_b,
> - };
> -
> - stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> -
> - validate_assert(kunit_binary_str_assert_format, test,
> - &binary_str_assert.assert,
> - stream, 5, "var_a", "var_b", "\"abacaba\"",
> - "\"kernel\"", "==");
> -
> - text.left_text = "\"abacaba\"";
> - validate_assert(kunit_binary_str_assert_format, test, &binary_str_assert.assert,
> - stream, 4, "\"abacaba\"", "var_b", "\"kernel\"", "==");
> -
> - text.right_text = "\"kernel\"";
> - validate_assert(kunit_binary_str_assert_format, test, &binary_str_assert.assert,
> - stream, 3, "\"abacaba\"", "\"kernel\"", "==");
> -}
> -
> -static const u8 hex_testbuf1[] = { 0x26, 0x74, 0x6b, 0x9c, 0x55,
> - 0x45, 0x9d, 0x47, 0xd6, 0x47,
> - 0x2, 0x89, 0x8c, 0x81, 0x94,
> - 0x12, 0xfe, 0x01 };
> -static const u8 hex_testbuf2[] = { 0x26, 0x74, 0x6b, 0x9c, 0x55,
> - 0x45, 0x9d, 0x47, 0x21, 0x47,
> - 0xcd, 0x89, 0x24, 0x50, 0x94,
> - 0x12, 0xba, 0x01 };
> -static void kunit_test_assert_hexdump(struct kunit *test)
> -{
> - struct string_stream *stream;
> - char *str;
> - size_t i;
> - char buf[HEXDUMP_TEST_BUF_LEN];
> -
> - stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> - /* Check that we are getting output like <xx> for non-matching numbers. */
> - kunit_assert_hexdump(stream, hex_testbuf1, hex_testbuf2, sizeof(hex_testbuf1));
> - str = get_str_from_stream(test, stream);
> - for (i = 0; i < sizeof(hex_testbuf1); i++) {
> - snprintf(buf, HEXDUMP_TEST_BUF_LEN, "<%02x>", hex_testbuf1[i]);
> - if (hex_testbuf1[i] != hex_testbuf2[i])
> - ASSERT_TEST_EXPECT_CONTAIN(test, str, buf);
> - }
> - /* We shouldn't get any <xx> numbers when comparing the buffer with itself. */
> - string_stream_clear(stream);
> - kunit_assert_hexdump(stream, hex_testbuf1, hex_testbuf1, sizeof(hex_testbuf1));
> - str = get_str_from_stream(test, stream);
> - ASSERT_TEST_EXPECT_NCONTAIN(test, str, "<");
> - ASSERT_TEST_EXPECT_NCONTAIN(test, str, ">");
> -}
> -
> -static void kunit_test_mem_assert_format(struct kunit *test)
> -{
> - struct string_stream *stream;
> - struct string_stream *expected_stream;
> - struct kunit_assert assert = {};
> - static const struct kunit_binary_assert_text text = {
> - .left_text = "hex_testbuf1",
> - .operation = "==",
> - .right_text = "hex_testbuf2",
> - };
> - struct kunit_mem_assert mem_assert = {
> - .assert = assert,
> - .text = &text,
> - .left_value = NULL,
> - .right_value = hex_testbuf2,
> - .size = sizeof(hex_testbuf1),
> - };
> -
> - expected_stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected_stream);
> - stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> -
> - /* The left value is NULL */
> - validate_assert(kunit_mem_assert_format, test, &mem_assert.assert,
> - stream, 2, "hex_testbuf1", "is not null");
> -
> - /* The right value is NULL, the left value is not NULL */
> - mem_assert.left_value = hex_testbuf1;
> - mem_assert.right_value = NULL;
> - validate_assert(kunit_mem_assert_format, test, &mem_assert.assert,
> - stream, 2, "hex_testbuf2", "is not null");
> -
> - /* Both arguments are not null */
> - mem_assert.left_value = hex_testbuf1;
> - mem_assert.right_value = hex_testbuf2;
> -
> - validate_assert(kunit_mem_assert_format, test, &mem_assert.assert,
> - stream, 3, "hex_testbuf1", "hex_testbuf2", "==");
> -}
> -
> -static struct kunit_case assert_test_cases[] = {
> - KUNIT_CASE(kunit_test_assert_is_literal),
> - KUNIT_CASE(kunit_test_assert_is_str_literal),
> - KUNIT_CASE(kunit_test_assert_prologue),
> - KUNIT_CASE(kunit_test_assert_print_msg),
> - KUNIT_CASE(kunit_test_unary_assert_format),
> - KUNIT_CASE(kunit_test_ptr_not_err_assert_format),
> - KUNIT_CASE(kunit_test_binary_assert_format),
> - KUNIT_CASE(kunit_test_binary_ptr_assert_format),
> - KUNIT_CASE(kunit_test_binary_str_assert_format),
> - KUNIT_CASE(kunit_test_assert_hexdump),
> - KUNIT_CASE(kunit_test_mem_assert_format),
> - {}
> -};
> -
> -static struct kunit_suite assert_test_suite = {
> - .name = "kunit-assert",
> - .test_cases = assert_test_cases,
> -};
> -
> -kunit_test_suites(&assert_test_suite);
> diff --git a/lib/kunit/kunit-test.c b/lib/kunit/kunit-test.c
> index d86f7cb3b3e4..71a3edde2ff4 100644
> --- a/lib/kunit/kunit-test.c
> +++ b/lib/kunit/kunit-test.c
> @@ -849,10 +849,387 @@ static struct kunit_suite kunit_current_test_suite = {
> .test_cases = kunit_current_test_cases,
> };
>
> +#define TEST_PTR_EXPECTED_BUF_SIZE 32
> +#define HEXDUMP_TEST_BUF_LEN 5
> +#define ASSERT_TEST_EXPECT_CONTAIN(test, str, substr) KUNIT_EXPECT_TRUE(test, strstr(str, substr))
> +#define ASSERT_TEST_EXPECT_NCONTAIN(test, str, substr) KUNIT_EXPECT_FALSE(test, strstr(str, substr))
> +
> +static void kunit_test_assert_is_literal(struct kunit *test)
> +{
> + KUNIT_EXPECT_TRUE(test, kunit_assert_is_literal("5", 5));
> + KUNIT_EXPECT_TRUE(test, kunit_assert_is_literal("0", 0));
> + KUNIT_EXPECT_TRUE(test, kunit_assert_is_literal("1234567890", 1234567890));
> + KUNIT_EXPECT_TRUE(test, kunit_assert_is_literal("-1234567890", -1234567890));
> + KUNIT_EXPECT_FALSE(test, kunit_assert_is_literal("05", 5));
> + KUNIT_EXPECT_FALSE(test, kunit_assert_is_literal("", 0));
> + KUNIT_EXPECT_FALSE(test, kunit_assert_is_literal("-0", 0));
> + KUNIT_EXPECT_FALSE(test, kunit_assert_is_literal("12#45", 1245));
> +}
> +
> +static void kunit_test_assert_is_str_literal(struct kunit *test)
> +{
> + KUNIT_EXPECT_TRUE(test, kunit_assert_is_str_literal("\"Hello, World!\"", "Hello, World!"));
> + KUNIT_EXPECT_TRUE(test, kunit_assert_is_str_literal("\"\"", ""));
> + KUNIT_EXPECT_TRUE(test, kunit_assert_is_str_literal("\"\"\"", "\""));
> + KUNIT_EXPECT_FALSE(test, kunit_assert_is_str_literal("", ""));
> + KUNIT_EXPECT_FALSE(test, kunit_assert_is_str_literal("\"", "\""));
> + KUNIT_EXPECT_FALSE(test, kunit_assert_is_str_literal("\"Abacaba", "Abacaba"));
> + KUNIT_EXPECT_FALSE(test, kunit_assert_is_str_literal("Abacaba\"", "Abacaba"));
> + KUNIT_EXPECT_FALSE(test, kunit_assert_is_str_literal("\"Abacaba\"", "\"Abacaba\""));
> +}
> +
> +/* this function is used to get a "char *" string from the string stream and defer its cleanup */
> +static char *get_str_from_stream(struct kunit *test, struct string_stream *stream)
> +{
> + char *str = string_stream_get_string(stream);
> +
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, str);
> + kunit_add_action(test, kfree_wrapper, (void *)str);
> +
> + return str;
> +}
> +
> +static void kunit_test_assert_prologue(struct kunit *test)
> +{
> + struct string_stream *stream;
> + char *str;
> + const struct kunit_loc location = {
> + .file = "testfile.c",
> + .line = 1337,
> + };
> +
> + stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> +
> + /* Test an expectation fail prologue */
> + kunit_assert_prologue(&location, KUNIT_EXPECTATION, stream);
> + str = get_str_from_stream(test, stream);
> + ASSERT_TEST_EXPECT_CONTAIN(test, str, "EXPECTATION");
> + ASSERT_TEST_EXPECT_CONTAIN(test, str, "testfile.c");
> + ASSERT_TEST_EXPECT_CONTAIN(test, str, "1337");
> +
> + /* Test an assertion fail prologue */
> + string_stream_clear(stream);
> + kunit_assert_prologue(&location, KUNIT_ASSERTION, stream);
> + str = get_str_from_stream(test, stream);
> + ASSERT_TEST_EXPECT_CONTAIN(test, str, "ASSERTION");
> + ASSERT_TEST_EXPECT_CONTAIN(test, str, "testfile.c");
> + ASSERT_TEST_EXPECT_CONTAIN(test, str, "1337");
> +}
> +
> +/*
> + * This function accepts an arbitrary count of parameters and generates a va_format struct,
> + * which can be used to validate kunit_assert_print_msg function
> + */
> +static void verify_assert_print_msg(struct kunit *test,
> + struct string_stream *stream,
> + char *expected, const char *format, ...)
> +{
> + va_list list;
> + const struct va_format vformat = {
> + .fmt = format,
> + .va = &list,
> + };
> +
> + va_start(list, format);
> + string_stream_clear(stream);
> + kunit_assert_print_msg(&vformat, stream);
> + KUNIT_EXPECT_STREQ(test, get_str_from_stream(test, stream), expected);
> +}
> +
> +static void kunit_test_assert_print_msg(struct kunit *test)
> +{
> + struct string_stream *stream;
> +
> + stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> +
> + verify_assert_print_msg(test, stream, "\nTest", "Test");
> + verify_assert_print_msg(test, stream, "\nAbacaba -123 234", "%s %d %u",
> + "Abacaba", -123, 234U);
> + verify_assert_print_msg(test, stream, "", NULL);
> +}
> +
> +/*
> + * Further code contains the tests for different assert format functions.
> + * This helper function accepts the assert format function, executes it and
> + * validates the result string from the stream by checking that all of the
> + * substrings exist in the output.
> + */
> +static void validate_assert(assert_format_t format_func, struct kunit *test,
> + const struct kunit_assert *assert,
> + struct string_stream *stream, int num_checks, ...)
> +{
> + size_t i;
> + va_list checks;
> + char *cur_substr_exp;
> + struct va_format message = { NULL, NULL };
> +
> + va_start(checks, num_checks);
> + string_stream_clear(stream);
> + format_func(assert, &message, stream);
> +
> + for (i = 0; i < num_checks; i++) {
> + cur_substr_exp = va_arg(checks, char *);
> + ASSERT_TEST_EXPECT_CONTAIN(test, get_str_from_stream(test, stream), cur_substr_exp);
> + }
> +}
> +
> +static void kunit_test_unary_assert_format(struct kunit *test)
> +{
> + struct string_stream *stream;
> + struct kunit_assert assert = {};
> + struct kunit_unary_assert un_assert = {
> + .assert = assert,
> + .condition = "expr",
> + .expected_true = true,
> + };
> +
> + stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> +
> + validate_assert(kunit_unary_assert_format, test, &un_assert.assert,
> + stream, 2, "true", "is false");
> +
> + un_assert.expected_true = false;
> + validate_assert(kunit_unary_assert_format, test, &un_assert.assert,
> + stream, 2, "false", "is true");
> +}
> +
> +static void kunit_test_ptr_not_err_assert_format(struct kunit *test)
> +{
> + struct string_stream *stream;
> + struct kunit_assert assert = {};
> + struct kunit_ptr_not_err_assert not_err_assert = {
> + .assert = assert,
> + .text = "expr",
> + .value = NULL,
> + };
> +
> + stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> +
> + /* Value is NULL. The corresponding message should be printed out */
> + validate_assert(kunit_ptr_not_err_assert_format, test,
> + ¬_err_assert.assert,
> + stream, 1, "null");
> +
> + /* Value is not NULL, but looks like an error pointer. Error should be printed out */
> + not_err_assert.value = (void *)-12;
> + validate_assert(kunit_ptr_not_err_assert_format, test,
> + ¬_err_assert.assert, stream, 2,
> + "error", "-12");
> +}
> +
> +static void kunit_test_binary_assert_format(struct kunit *test)
> +{
> + struct string_stream *stream;
> + struct kunit_assert assert = {};
> + struct kunit_binary_assert_text text = {
> + .left_text = "1 + 2",
> + .operation = "==",
> + .right_text = "2",
> + };
> + const struct kunit_binary_assert binary_assert = {
> + .assert = assert,
> + .text = &text,
> + .left_value = 3,
> + .right_value = 2,
> + };
> +
> + stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> +
> + /*
> + * Printed values should depend on the input we provide: the left text, right text, left
> + * value and the right value.
> + */
> + validate_assert(kunit_binary_assert_format, test, &binary_assert.assert,
> + stream, 4, "1 + 2", "2", "3", "==");
> +
> + text.right_text = "4 - 2";
> + validate_assert(kunit_binary_assert_format, test, &binary_assert.assert,
> + stream, 3, "==", "1 + 2", "4 - 2");
> +
> + text.left_text = "3";
> + validate_assert(kunit_binary_assert_format, test, &binary_assert.assert,
> + stream, 4, "3", "4 - 2", "2", "==");
> +
> + text.right_text = "2";
> + validate_assert(kunit_binary_assert_format, test, &binary_assert.assert,
> + stream, 3, "3", "2", "==");
> +}
> +
> +static void kunit_test_binary_ptr_assert_format(struct kunit *test)
> +{
> + struct string_stream *stream;
> + struct kunit_assert assert = {};
> + char *addr_var_a, *addr_var_b;
> + static const void *var_a = (void *)0xDEADBEEF;
> + static const void *var_b = (void *)0xBADDCAFE;
> + struct kunit_binary_assert_text text = {
> + .left_text = "var_a",
> + .operation = "==",
> + .right_text = "var_b",
> + };
> + struct kunit_binary_ptr_assert binary_ptr_assert = {
> + .assert = assert,
> + .text = &text,
> + .left_value = var_a,
> + .right_value = var_b,
> + };
> +
> + addr_var_a = kunit_kzalloc(test, TEST_PTR_EXPECTED_BUF_SIZE, GFP_KERNEL);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, addr_var_a);
> + addr_var_b = kunit_kzalloc(test, TEST_PTR_EXPECTED_BUF_SIZE, GFP_KERNEL);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, addr_var_b);
> + /*
> + * Print the addresses to the buffers first.
> + * This is necessary as we may have different count of leading zeros in the pointer
> + * on different architectures.
> + */
> + snprintf(addr_var_a, TEST_PTR_EXPECTED_BUF_SIZE, "%px", var_a);
> + snprintf(addr_var_b, TEST_PTR_EXPECTED_BUF_SIZE, "%px", var_b);
This use of %px is flagged here as a checkpatch warning. However,
since this functionality would not work if we just used %p, I think we
can make the case that the use of %px is necessary here. Shuah, let me
know what you think?
> +
> + stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> + validate_assert(kunit_binary_ptr_assert_format, test, &binary_ptr_assert.assert,
> + stream, 3, addr_var_a, addr_var_b, "==");
> +}
> +
> +static void kunit_test_binary_str_assert_format(struct kunit *test)
> +{
> + struct string_stream *stream;
> + struct kunit_assert assert = {};
> + static const char *var_a = "abacaba";
> + static const char *var_b = "kernel";
> + struct kunit_binary_assert_text text = {
> + .left_text = "var_a",
> + .operation = "==",
> + .right_text = "var_b",
> + };
> + struct kunit_binary_str_assert binary_str_assert = {
> + .assert = assert,
> + .text = &text,
> + .left_value = var_a,
> + .right_value = var_b,
> + };
> +
> + stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> +
> + validate_assert(kunit_binary_str_assert_format, test,
> + &binary_str_assert.assert,
> + stream, 5, "var_a", "var_b", "\"abacaba\"",
> + "\"kernel\"", "==");
> +
> + text.left_text = "\"abacaba\"";
> + validate_assert(kunit_binary_str_assert_format, test, &binary_str_assert.assert,
> + stream, 4, "\"abacaba\"", "var_b", "\"kernel\"", "==");
> +
> + text.right_text = "\"kernel\"";
> + validate_assert(kunit_binary_str_assert_format, test, &binary_str_assert.assert,
> + stream, 3, "\"abacaba\"", "\"kernel\"", "==");
> +}
> +
> +static const u8 hex_testbuf1[] = { 0x26, 0x74, 0x6b, 0x9c, 0x55,
> + 0x45, 0x9d, 0x47, 0xd6, 0x47,
> + 0x2, 0x89, 0x8c, 0x81, 0x94,
> + 0x12, 0xfe, 0x01 };
> +static const u8 hex_testbuf2[] = { 0x26, 0x74, 0x6b, 0x9c, 0x55,
> + 0x45, 0x9d, 0x47, 0x21, 0x47,
> + 0xcd, 0x89, 0x24, 0x50, 0x94,
> + 0x12, 0xba, 0x01 };
> +static void kunit_test_assert_hexdump(struct kunit *test)
> +{
> + struct string_stream *stream;
> + char *str;
> + size_t i;
> + char buf[HEXDUMP_TEST_BUF_LEN];
> +
> + stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> + /* Check that we are getting output like <xx> for non-matching numbers. */
> + kunit_assert_hexdump(stream, hex_testbuf1, hex_testbuf2, sizeof(hex_testbuf1));
> + str = get_str_from_stream(test, stream);
> + for (i = 0; i < sizeof(hex_testbuf1); i++) {
> + snprintf(buf, HEXDUMP_TEST_BUF_LEN, "<%02x>", hex_testbuf1[i]);
> + if (hex_testbuf1[i] != hex_testbuf2[i])
> + ASSERT_TEST_EXPECT_CONTAIN(test, str, buf);
> + }
> + /* We shouldn't get any <xx> numbers when comparing the buffer with itself. */
> + string_stream_clear(stream);
> + kunit_assert_hexdump(stream, hex_testbuf1, hex_testbuf1, sizeof(hex_testbuf1));
> + str = get_str_from_stream(test, stream);
> + ASSERT_TEST_EXPECT_NCONTAIN(test, str, "<");
> + ASSERT_TEST_EXPECT_NCONTAIN(test, str, ">");
> +}
> +
> +static void kunit_test_mem_assert_format(struct kunit *test)
> +{
> + struct string_stream *stream;
> + struct string_stream *expected_stream;
> + struct kunit_assert assert = {};
> + static const struct kunit_binary_assert_text text = {
> + .left_text = "hex_testbuf1",
> + .operation = "==",
> + .right_text = "hex_testbuf2",
> + };
> + struct kunit_mem_assert mem_assert = {
> + .assert = assert,
> + .text = &text,
> + .left_value = NULL,
> + .right_value = hex_testbuf2,
> + .size = sizeof(hex_testbuf1),
> + };
> +
> + expected_stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected_stream);
> + stream = kunit_alloc_string_stream(test, GFP_KERNEL);
> + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, stream);
> +
> + /* The left value is NULL */
> + validate_assert(kunit_mem_assert_format, test, &mem_assert.assert,
> + stream, 2, "hex_testbuf1", "is not null");
> +
> + /* The right value is NULL, the left value is not NULL */
> + mem_assert.left_value = hex_testbuf1;
> + mem_assert.right_value = NULL;
> + validate_assert(kunit_mem_assert_format, test, &mem_assert.assert,
> + stream, 2, "hex_testbuf2", "is not null");
> +
> + /* Both arguments are not null */
> + mem_assert.left_value = hex_testbuf1;
> + mem_assert.right_value = hex_testbuf2;
> +
> + validate_assert(kunit_mem_assert_format, test, &mem_assert.assert,
> + stream, 3, "hex_testbuf1", "hex_testbuf2", "==");
> +}
> +
> +static struct kunit_case kunit_assert_test_cases[] = {
> + KUNIT_CASE(kunit_test_assert_is_literal),
> + KUNIT_CASE(kunit_test_assert_is_str_literal),
> + KUNIT_CASE(kunit_test_assert_prologue),
> + KUNIT_CASE(kunit_test_assert_print_msg),
> + KUNIT_CASE(kunit_test_unary_assert_format),
> + KUNIT_CASE(kunit_test_ptr_not_err_assert_format),
> + KUNIT_CASE(kunit_test_binary_assert_format),
> + KUNIT_CASE(kunit_test_binary_ptr_assert_format),
> + KUNIT_CASE(kunit_test_binary_str_assert_format),
> + KUNIT_CASE(kunit_test_assert_hexdump),
> + KUNIT_CASE(kunit_test_mem_assert_format),
> + {}
> +};
> +
> +static struct kunit_suite kunit_assert_test_suite = {
> + .name = "kunit-assert",
> + .test_cases = kunit_assert_test_cases,
> +};
> +
> kunit_test_suites(&kunit_try_catch_test_suite, &kunit_resource_test_suite,
> &kunit_log_test_suite, &kunit_status_test_suite,
> &kunit_current_test_suite, &kunit_device_test_suite,
> - &kunit_fault_test_suite);
> + &kunit_fault_test_suite, &kunit_assert_test_suite);
>
> MODULE_DESCRIPTION("KUnit test for core test infrastructure");
> MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING);
> --
> 2.34.1
>
Powered by blists - more mailing lists