Re: [PATCH 2/4] kunit: Fix indentation level of suite messages

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 28.09.2023 22:52, Rae Moar wrote:
> On Mon, Sep 25, 2023 at 1:58 PM Michal Wajdeczko
> <michal.wajdeczko@xxxxxxxxx> wrote:
>>
>> A kunit suite is a top level test from the KTAP point of view but
>> all suite diagnostic messages are printed at the subtest level:
>>
>>     $ ./tools/testing/kunit/kunit.py run --raw_output \
>>         --kunitconfig ./lib/kunit/.kunitconfig "example.*simple*"
>>
>>     KTAP version 1
>>     1..1
>>         # example: initializing suite
>>         # example: failed to initialize (-ENODEV)
>>     not ok 1 example
>>
>>     KTAP version 1
>>     1..1
>>         # example: initializing suite
>>         KTAP version 1
>>         # Subtest: example
>>         # module: kunit_example_test
>>         1..1
>>         # example_simple_test: initializing
>>         # example_simple_test: cleaning up
>>         ok 1 example_simple_test
>>         # example: exiting suite
>>     ok 1 example
>>
>> Replace hardcoded indent in kunit_printk() with flexible
>> indentation based on the argument type (test or suite):
>>
>>     KTAP version 1
>>     1..1
>>     # example: initializing suite
>>     # example: failed to initialize (-ENODEV)
>>     not ok 1 example
>>
>>     KTAP version 1
>>     1..1
>>     # example: initializing suite
>>         KTAP version 1
>>         # Subtest: example
>>         # module: kunit_example_test
>>         1..1
>>         # example_simple_test: initializing
>>         # example_simple_test: cleaning up
>>         ok 1 example_simple_test
>>     # example: exiting suite
>>     ok 1 example
> 
> Hi!
> 
> I am happy to see this change to improve the indentation of
> parameterized tests. It has been bugging me for a bit. This seems to
> be working well but I just had a few comments to potentially discuss.
> 
> Thanks!
> 
> -Rae
> 
>>
>> Signed-off-by: Michal Wajdeczko <michal.wajdeczko@xxxxxxxxx>
>> Cc: David Gow <davidgow@xxxxxxxxxx>
>> Cc: Rae Moar <rmoar@xxxxxxxxxx>
>> ---
>>  include/kunit/test.h | 24 ++++++++++++++++++++++--
>>  lib/kunit/test.c     |  7 -------
>>  2 files changed, 22 insertions(+), 9 deletions(-)
>>
>> diff --git a/include/kunit/test.h b/include/kunit/test.h
>> index 20ed9f9275c9..158876c4cb43 100644
>> --- a/include/kunit/test.h
>> +++ b/include/kunit/test.h
>> @@ -509,6 +509,21 @@ void __printf(2, 3) kunit_log_append(struct string_stream *log, const char *fmt,
>>                 kunit_try_catch_throw(&((test_or_suite)->try_catch));   \
>>         } while (0)
>>
>> +/* Currently supported test levels */
>> +enum {
>> +       KUNIT_LEVEL_SUITE = 0,
>> +       KUNIT_LEVEL_CASE,
>> +       KUNIT_LEVEL_CASE_PARAM,
>> +};
> 
> I do find this slightly confusing to have a KUNIT_LEVEL_SUITE as the
> suite output occurs on multiple levels. Plus, I also don't see any
> uses of the SUITE level or the PARAM level anymore. Do you have any
> ideas on this?

This enum was just promoted as-is from the test.c as I didn't want to
use magic 0 or 1 in below kunit_level() macro.

Note that the KUNIT_LEVEL_SUITE is now used indirectly whenever you call
any of kunit_printk() with suite param like here:

./kunit-example-test.c:60:  kunit_info(suite, "initializing suite\n");
./kunit-example-test.c:71:  kunit_info(suite, "exiting suite\n");

as this will result in calls to kunit_indent_level(suite) and
kunit_level(suite) macro.

And KUNIT_LEVEL_CASE_PARAM is maybe a leftover, as now we change test
levels using direct increase/decrease statements, but still IMO this
enum nicely reflects what kind of levels we currently do support at this
point. But could be dropped if needed.

Regarding _"suite output occurs on multiple levels"_ I found that also
confusing, but IMO this is due to the kunit implementation details
and/or KTAP design decisions as it looks that "suite" is treated
sometimes as "subtest" and sometimes as a top level "test".

That makes a little trouble while trying to implement printing in a
consistent manner.  Maybe we should consider introducing concept of the
"executor" with its own level attribute? Then mapping will be like this:

KTAP version 1				<- kunit executor (level=0)
1..1					<- kunit executor (level=0)
# Test: example				<- kunit executor (level=0) ??
# module: kunit_example_test		<- kunit executor (level=0) ??
# example: initializing suite		<- suite (test level=0)
    KTAP version 1			<- suite executor (level=1)
    # Subtest: example			<- suite executor (level=1)
    # module: kunit_example_test	<- suite executor (level=1)
    1..2				<- suite executor (level=1)
    # test_1: initializing		<- test_case (test level=1)
    # test_1: cleaning up		<- test_case (test level=1)
    # test_1: pass:1 fail:0 skip:0 tota <- suite executor (level=1)
    ok 1 test_1				<- suite executor (level=1)
        KTAP version 1			<- params executor (level=2)
        # Subtest: test_2		<- params executor (level=2)
        1..2				<- params executor (level=2)
        # test_2: initializing		<- test_case (test level=2)
        # test_2: cleaning up		<- test_case (test level=2)
        ok 1 example value 1		<- params executor (level=2)
        # test_2: initializing		<- test_case (test level=2)
        # test_2: cleaning up		<- test_case (test level=2)
        ok 2 example value 0		<- params executor (level=2)
    # test_2: pass:2 fail:0 skip:0 tota <- suite executor (level=1)
    ok 2 test_2				<- suite executor (level=1)
# example: exiting suite		<- suite (test level=0)
# example: pass:2 fail:0 skip:0 total:2	<- kunit executor (level=0)
# Totals: pass:3 fail:0 skip:0 total:3	<- kunit executor (level=0)
ok 1 example				<- kunit executor (level=0)

Then any suite and/or test level will be just based on executor.level
This could be done as follow-up improvement.

> 
> We could consider just using the test->level field introduced in the
> next patch to manage the levels. Or I wouldn't mind keeping this just
> for clarity?

We still need some definition for initial level, no?
And at this point in series, we still need at least two defs.

> 
>> +
>> +#define kunit_level(test_or_suite)                                     \
>> +       _Generic((test_or_suite),                                       \
>> +                struct kunit_suite * : KUNIT_LEVEL_SUITE,              \
>> +                struct kunit * : KUNIT_LEVEL_CASE)
>> +
> 
> I am not super familiar with using _Generic so I would want David's opinion.
> 
> Also I can think of cases where it would be helpful to add an option
> for struct kunit_case *, however, that may be an addition for the
> future.

I had entry for struct kunit_test_case* but removed that as it was never
used in current code (no calls to kunit_log() with test_case)

> 
> And then additionally, this macro seems to be only used for the struct
> kunit * case. Will we plan to use this in the future for suites?

As pointed above we already use it for test and suite:

./kunit-example-test.c:60:  kunit_info(suite, "initializing suite\n");
./kunit-example-test.c:71:  kunit_info(suite, "exiting suite\n");

> 
>> +#define kunit_indent_level(test_or_suite)                              \
>> +       (KUNIT_INDENT_LEN * kunit_level(test_or_suite))
>> +
>>  /*
>>   * printk and log to per-test or per-suite log buffer.  Logging only done
>>   * if CONFIG_KUNIT_DEBUGFS is 'y'; if it is 'n', no log is allocated/used.
>> @@ -520,9 +535,14 @@ void __printf(2, 3) kunit_log_append(struct string_stream *log, const char *fmt,
>>                                  ##__VA_ARGS__);                        \
>>         } while (0)
>>
>> +#define kunit_log_indent(lvl, test_or_suite, fmt, ...)                 \
>> +       kunit_log(lvl, test_or_suite, "%*s" fmt,                        \
>> +                 kunit_indent_level(test_or_suite), "",                \
>> +                 ##__VA_ARGS__)
>> +
>>  #define kunit_printk(lvl, test, fmt, ...)                              \
>> -       kunit_log(lvl, test, KUNIT_SUBTEST_INDENT "# %s: " fmt,         \
>> -                 (test)->name, ##__VA_ARGS__)
>> +       kunit_log_indent(lvl, test, "# %s: " fmt,                       \
>> +                        (test)->name, ##__VA_ARGS__)
>>
> 
> I wonder if we could consider removing the need to use
> KUNIT_SUBTEST_INDENT in all locations. I am primarily thinking about
> its uses in debugfs.c and test.c.
> 
> For example in debugfs.c:
> pr_info(KUNIT_SUBTEST_INDENT "KTAP version 1\n");
> 
> Although, as this is a suite object that is printing at the test case
> level, I am not quite sure how to use the existing macros.

We could add some wrapper like kunit_pr() that takes suite/test/executor
from which we can derive right indent level, but that would be another
follow up task once we agree on location and use of .level attribute.

Michal

> 
> 
>>  /**
>>   * kunit_info() - Prints an INFO level message associated with @test.
>> diff --git a/lib/kunit/test.c b/lib/kunit/test.c
>> index fb5981ce578d..d10e6d610e20 100644
>> --- a/lib/kunit/test.c
>> +++ b/lib/kunit/test.c
>> @@ -135,13 +135,6 @@ size_t kunit_suite_num_test_cases(struct kunit_suite *suite)
>>  }
>>  EXPORT_SYMBOL_GPL(kunit_suite_num_test_cases);
>>
>> -/* Currently supported test levels */
>> -enum {
>> -       KUNIT_LEVEL_SUITE = 0,
>> -       KUNIT_LEVEL_CASE,
>> -       KUNIT_LEVEL_CASE_PARAM,
>> -};
>> -
>>  static void kunit_print_suite_start(struct kunit_suite *suite)
>>  {
>>         /*
>> --
>> 2.25.1
>>



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux