Re: [PATCH v2 1/3] kunit: Introduce KUNIT_EXPECT_MEMEQ and KUNIT_EXPECT_MEMNEQ macros

From: Daniel Latypov
Date: Tue Aug 02 2022 - 18:25:10 EST


On Tue, Aug 2, 2022 at 2:26 PM Maíra Canal <mairacanal@xxxxxxxxxx> wrote:
>
> Currently, in order to compare memory blocks in KUnit, the KUNIT_EXPECT_EQ
> or KUNIT_EXPECT_FALSE macros are used in conjunction with the memcmp
> function, such as:
> KUNIT_EXPECT_EQ(test, memcmp(foo, bar, size), 0);
>
> Although this usage produces correct results for the test cases, when
> the expectation fails, the error message is not very helpful,
> indicating only the return of the memcmp function.
>
> Therefore, create a new set of macros KUNIT_EXPECT_MEMEQ and
> KUNIT_EXPECT_MEMNEQ that compare memory blocks until a specified size.
> In case of expectation failure, those macros print the hex dump of the
> memory blocks, making it easier to debug test failures for memory blocks.
>
> That said, the expectation
>
> KUNIT_EXPECT_EQ(test, memcmp(foo, bar, size), 0);
>
> would translate to the expectation
>
> KUNIT_EXPECT_MEMEQ(test, foo, bar, size);
>
> Signed-off-by: Maíra Canal <mairacanal@xxxxxxxxxx>

Reviewed-by: Daniel Latypov <dlatypov@xxxxxxxxxx>
Thanks, this is nice to have and I think the clarity issues have been resolved.

Some various optional nits about whitespace below.
I'd see if anyone has any complaints about the output format before
wasting any time on those nits.

Looking at example output now, I see
Expected array2 == array1, but
array2 ==
<1f> 00 00 00 ff 00 00 00
array1 ==
<0f> 00 00 00 ff 00 00 00
not ok 4 - example_all_expect_macros_test

Looks good to me.

> ---
> v1 -> v2:
> - Change "determinated" to "specified" (Daniel Latypov).
> - Change the macro KUNIT_EXPECT_ARREQ to KUNIT_EXPECT_MEMEQ, in order to make
> it easier for users to infer the right size unit (Daniel Latypov).
> - Mark the different bytes on the failure message with a <> (Daniel Latypov).
> ---
> include/kunit/assert.h | 35 +++++++++++++++++++
> include/kunit/test.h | 76 ++++++++++++++++++++++++++++++++++++++++++
> lib/kunit/assert.c | 54 ++++++++++++++++++++++++++++++
> 3 files changed, 165 insertions(+)
>
> diff --git a/include/kunit/assert.h b/include/kunit/assert.h
> index 4b52e12c2ae8..a54f5253b997 100644
> --- a/include/kunit/assert.h
> +++ b/include/kunit/assert.h
> @@ -256,4 +256,39 @@ void kunit_binary_str_assert_format(const struct kunit_assert *assert,
> const struct va_format *message,
> struct string_stream *stream);
>
> +
> +#define KUNIT_INIT_MEM_ASSERT_STRUCT(text_, left_val, right_val, size_) \
> + { \
> + .assert = { .format = kunit_mem_assert_format }, \
> + .text = text_, \
> + .left_value = left_val, \
> + .right_value = right_val, .size = size_, \
> + }

very nit: the trailing \s aren't quite lined up.
In this particular case, I'm planning on deleting this block in the
future, so it doesn't matter too much.

> diff --git a/include/kunit/test.h b/include/kunit/test.h
> index 8ffcd7de9607..1925d648eec8 100644
> --- a/include/kunit/test.h
> +++ b/include/kunit/test.h
> @@ -684,6 +684,36 @@ do { \
> ##__VA_ARGS__); \
> } while (0)
>
> +#define KUNIT_MEM_ASSERTION(test, \

very nit: the trailing \s are also a bit out of line here.
We can fix this particular line by just adding another \t after "test,"

In general, lining these up is just a matter of adding a \t after the
text and then maybe add or delete some of the " "s before the \s.
E.g. with vim's `:set list`, after lining up the \s, I get

#define KUNIT_MEM_ASSERTION(test,^I^I^I^I^I \$
^I^I^I^I assert_type,^I^I^I^I \$
^I^I^I^I left,^I^I^I^I \$
^I^I^I^I op,^I^I^I^I^I \$
^I^I^I^I right,^I^I^I^I \$
^I^I^I^I size,^I^I \$
^I^I^I^I fmt,^I^I^I^I^I \$
^I^I^I^I ...)^I^I^I^I^I \$
do {^I^I^I^I^I^I^I^I^I \$
^Iconst void *__left = (left);^I^I^I^I^I \$
...

> diff --git a/lib/kunit/assert.c b/lib/kunit/assert.c
> index d00d6d181ee8..abd434bc7ec6 100644
> --- a/lib/kunit/assert.c
> +++ b/lib/kunit/assert.c
> @@ -204,3 +204,57 @@ void kunit_binary_str_assert_format(const struct kunit_assert *assert,
> kunit_assert_print_msg(message, stream);
> }
> EXPORT_SYMBOL_GPL(kunit_binary_str_assert_format);
> +
> +/* Adds a hexdump of a buffer to a string_stream comparing it with
> + * a second buffer. The different bytes are marked with <>.
> + */
> +static void kunit_assert_hexdump(struct string_stream *stream,
> + const void *buf, const void *compared_buf, const size_t len)
> +{
> + size_t i;
> + const u8 *buf1 = buf;
> + const u8 *buf2 = compared_buf;
> +
> + for (i = 0; i < len; ++i) {
> + if (i % 16)
> + string_stream_add(stream, " ");
> + else if (i)
> + string_stream_add(stream, "\n ");
> +
> + if (buf1[i] != buf2[i])
> + string_stream_add(stream, "<%02x>", buf1[i]);
> + else
> + string_stream_add(stream, "%02x", buf1[i]);
> + }
> +}
> +
> +void kunit_mem_assert_format(const struct kunit_assert *assert,
> + const struct va_format *message,
> + struct string_stream *stream)

very nit: the func above doesn't line up the params, but I don't think
it matters too much.
It uses \t\t whereas this one is \t\t\t + some spaces.

I think it'd be fine if they were consistent with each other, or if
you're willing to mess around with spaces, we could get the parameters
to line up.
(e.g. see how kunit_binary_ptr_assert_format and others do their line breaks)