Message ID | 20240618170331.264851-6-ivan.orlov0322@gmail.com (mailing list archive) |
---|---|
State | New |
Delegated to: | Brendan Higgins |
Headers | show |
Series | Reorganize string-stream and assert tests | expand |
On Tue, Jun 18, 2024 at 1:03 PM Ivan Orlov <ivan.orlov0322@gmail.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@gmail.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@google.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@gmail.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 >
On 6/21/24 22:38, Rae Moar wrote: > On Tue, Jun 18, 2024 at 1:03 PM Ivan Orlov <ivan.orlov0322@gmail.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@gmail.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@google.com> > > Thanks! > -Rae > Hi Rae, Thank you so much for the review, and sorry for the late reply ( I've been on vacation this week, and didn't have access to my inbox :( ). And yes, since we want to get the actual pointer address "%px" is our only option :(
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@gmail.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); + + 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);
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@gmail.com> --- 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