Documentation: kunit: Add naming guidelines
diff mbox series

Message ID 20200702071416.1780522-1-davidgow@google.com
State New
Headers show
Series
  • Documentation: kunit: Add naming guidelines
Related show

Commit Message

David Gow July 2, 2020, 7:14 a.m. UTC
As discussed in [1], KUnit tests have hitherto not had a particularly
consistent naming scheme. This adds documentation outlining how tests
and test suites should be named, including how those names should be
used in Kconfig entries and filenames.

[1]:
https://lore.kernel.org/linux-kselftest/202006141005.BA19A9D3@keescook/t/#u

Signed-off-by: David Gow <davidgow@google.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
---
This is a follow-up v1 to the RFC patch here:
https://lore.kernel.org/linux-kselftest/20200620054944.167330-1-davidgow@google.com/T/#u

There weren't any fundamental objections to the naming guidelines
themselves, so nothing's changed on that front.

Otherwise, changes since the RFC:
- Fixed a bit of space/tab confusion in the index (Thanks, Randy)
- Added some more examples (and some test case examples).
- Added some examples of what not to call subsystems and suites.
- No longer explicitly require "If unsure, put N" in Kconfig entries.
- Minor formatting changes.

Cheers,
-- David

 Documentation/dev-tools/kunit/index.rst |   1 +
 Documentation/dev-tools/kunit/style.rst | 181 ++++++++++++++++++++++++
 2 files changed, 182 insertions(+)
 create mode 100644 Documentation/dev-tools/kunit/style.rst

Comments

Brendan Higgins July 31, 2020, 10:02 p.m. UTC | #1
On Thu, Jul 2, 2020 at 12:14 AM David Gow <davidgow@google.com> wrote:
>
> As discussed in [1], KUnit tests have hitherto not had a particularly
> consistent naming scheme. This adds documentation outlining how tests
> and test suites should be named, including how those names should be
> used in Kconfig entries and filenames.
>
> [1]:
> https://lore.kernel.org/linux-kselftest/202006141005.BA19A9D3@keescook/t/#u
>
> Signed-off-by: David Gow <davidgow@google.com>
> Reviewed-by: Kees Cook <keescook@chromium.org>

Sorry for taking so long on this; nevertheless, looks great!

Reviewed-by: Brendan Higgins <brendanhiggins@google.com>
Marco Elver Aug. 27, 2020, 1:14 p.m. UTC | #2
On Thu, Jul 02, 2020 at 12:14AM -0700, David Gow wrote:
> As discussed in [1], KUnit tests have hitherto not had a particularly
> consistent naming scheme. This adds documentation outlining how tests
> and test suites should be named, including how those names should be
> used in Kconfig entries and filenames.
> 
> [1]:
> https://lore.kernel.org/linux-kselftest/202006141005.BA19A9D3@keescook/t/#u
> 
> Signed-off-by: David Gow <davidgow@google.com>
> Reviewed-by: Kees Cook <keescook@chromium.org>
> ---
...
> +An example Kconfig entry:
> +
> +.. code-block:: none
> +
> +        config FOO_KUNIT_TEST
> +                tristate "KUnit test for foo" if !KUNIT_ALL_TESTS
> +                depends on KUNIT
> +                default KUNIT_ALL_TESTS
> +                help
> +                    This builds unit tests for foo.
> +
> +                    For more information on KUnit and unit tests in general, please refer
> +                    to the KUnit documentation in Documentation/dev-tools/kunit
> +
> +                    If unsure, say N
> +
> +
> +Test Filenames
> +==============
> +
> +Where possible, test suites should be placed in a separate source file in the
> +same directory as the code being tested.
> +
> +This file should be named ``<suite>_kunit.c``. It may make sense to strip
> +excessive namespacing from the source filename (e.g., ``firmware_kunit.c`` instead of
> +``<drivername>_firmware.c``), but please ensure the module name does contain the
> +full suite name.

First of all, thanks for the talk yesterday! I only looked at this
because somebody pasted the LKML link. :-)

The example about excessive namespacing seems confusing. Was it supposed
to be 

	[...] firmware_kunit.c`` instead of ``<drivername>_firmware_kunit.c [...]

?


While I guess this ship has sailed, and *_kunit.c is the naming
convention now, I hope this is still just a recommendation and names of
the form *-test.c are not banned!

$> git grep 'KUNIT.*-test.o'
	drivers/base/power/Makefile:obj-$(CONFIG_PM_QOS_KUNIT_TEST) += qos-test.o
	drivers/base/test/Makefile:obj-$(CONFIG_KUNIT_DRIVER_PE_TEST) += property-entry-test.o
	fs/ext4/Makefile:obj-$(CONFIG_EXT4_KUNIT_TESTS)		+= ext4-inode-test.o
	kernel/Makefile:obj-$(CONFIG_SYSCTL_KUNIT_TEST) += sysctl-test.o
	lib/Makefile:obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o
	lib/kunit/Makefile:obj-$(CONFIG_KUNIT_TEST) +=		kunit-test.o
	lib/kunit/Makefile:obj-$(CONFIG_KUNIT_TEST) +=		string-stream-test.o
	lib/kunit/Makefile:obj-$(CONFIG_KUNIT_EXAMPLE_TEST) +=	kunit-example-test.o

$> git grep 'KUNIT.*_kunit.o'
# Returns nothing


Just an idea: Maybe the names are also an opportunity to distinguish
real _unit_ style tests and then the rarer integration-style tests. I
personally prefer using the more generic *-test.c, at least for the
integration-style tests I've been working on (KUnit is still incredibly
valuable for integration-style tests, because otherwise I'd have to roll
my own poor-man's version of KUnit, so thank you!). Using *_kunit.c for
such tests is unintuitive, because the word "unit" hints at "unit tests"
-- and having descriptive (and not misleading) filenames is still
important. So I hope you won't mind if *-test.c are still used where
appropriate.

Thanks,
-- Marco
David Gow Aug. 27, 2020, 4:17 p.m. UTC | #3
On Thu, Aug 27, 2020 at 9:14 PM Marco Elver <elver@google.com> wrote:
>
> On Thu, Jul 02, 2020 at 12:14AM -0700, David Gow wrote:
> > As discussed in [1], KUnit tests have hitherto not had a particularly
> > consistent naming scheme. This adds documentation outlining how tests
> > and test suites should be named, including how those names should be
> > used in Kconfig entries and filenames.
> >
> > [1]:
> > https://lore.kernel.org/linux-kselftest/202006141005.BA19A9D3@keescook/t/#u
> >
> > Signed-off-by: David Gow <davidgow@google.com>
> > Reviewed-by: Kees Cook <keescook@chromium.org>
> > ---
> ...
> > +An example Kconfig entry:
> > +
> > +.. code-block:: none
> > +
> > +        config FOO_KUNIT_TEST
> > +                tristate "KUnit test for foo" if !KUNIT_ALL_TESTS
> > +                depends on KUNIT
> > +                default KUNIT_ALL_TESTS
> > +                help
> > +                    This builds unit tests for foo.
> > +
> > +                    For more information on KUnit and unit tests in general, please refer
> > +                    to the KUnit documentation in Documentation/dev-tools/kunit
> > +
> > +                    If unsure, say N
> > +
> > +
> > +Test Filenames
> > +==============
> > +
> > +Where possible, test suites should be placed in a separate source file in the
> > +same directory as the code being tested.
> > +
> > +This file should be named ``<suite>_kunit.c``. It may make sense to strip
> > +excessive namespacing from the source filename (e.g., ``firmware_kunit.c`` instead of
> > +``<drivername>_firmware.c``), but please ensure the module name does contain the
> > +full suite name.
>
> First of all, thanks for the talk yesterday! I only looked at this
> because somebody pasted the LKML link. :-)

No worries! Clearly this document needed linking -- even I was
starting to suspect the reason no-one was complaining about this was
that no-one had read it. :-)

> The example about excessive namespacing seems confusing. Was it supposed
> to be
>
>         [...] firmware_kunit.c`` instead of ``<drivername>_firmware_kunit.c [...]
>
> ?

Whoops, yes. I'll fix that.

>
> While I guess this ship has sailed, and *_kunit.c is the naming
> convention now, I hope this is still just a recommendation and names of
> the form *-test.c are not banned!

The ship hasn't technically sailed until this patch is actually
accepted. Thus far, we hadn't had any real complaints about the
_kunit.c idea, though that may have been due to this email not
reaching enough people. If you haven't read the discussion in
https://lore.kernel.org/linux-kselftest/202006141005.BA19A9D3@keescook/t/#u
it's worthwhile: the _kunit.c name is discussed, and Kees lays out
some more detailed rationale for it as well.

> $> git grep 'KUNIT.*-test.o'
>         drivers/base/power/Makefile:obj-$(CONFIG_PM_QOS_KUNIT_TEST) += qos-test.o
>         drivers/base/test/Makefile:obj-$(CONFIG_KUNIT_DRIVER_PE_TEST) += property-entry-test.o
>         fs/ext4/Makefile:obj-$(CONFIG_EXT4_KUNIT_TESTS)         += ext4-inode-test.o
>         kernel/Makefile:obj-$(CONFIG_SYSCTL_KUNIT_TEST) += sysctl-test.o
>         lib/Makefile:obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o
>         lib/kunit/Makefile:obj-$(CONFIG_KUNIT_TEST) +=          kunit-test.o
>         lib/kunit/Makefile:obj-$(CONFIG_KUNIT_TEST) +=          string-stream-test.o
>         lib/kunit/Makefile:obj-$(CONFIG_KUNIT_EXAMPLE_TEST) +=  kunit-example-test.o
>
> $> git grep 'KUNIT.*_kunit.o'
> # Returns nothing
>

This was definitely something we noted. Part of the goal of having
_kunit.c as a filename suffix (and, perhaps more importantly, the
_kunit module name suffix) was to have a way of both distinguishing
KUnit tests from non-KUnit ones (of which there are quite a few
already with -test names), and to have a way of quickly determining
what modules contain KUnit tests. That really only works if everyone
is using it, so the plan was to push this as much as possible. This'd
probably include renaming most of the existing test files to match,
which is a bit of a pain (particularly when converting non-KUnit tests
to KUnit and similar), but is a one-time thing.

>
> Just an idea: Maybe the names are also an opportunity to distinguish
> real _unit_ style tests and then the rarer integration-style tests. I
> personally prefer using the more generic *-test.c, at least for the
> integration-style tests I've been working on (KUnit is still incredibly
> valuable for integration-style tests, because otherwise I'd have to roll
> my own poor-man's version of KUnit, so thank you!). Using *_kunit.c for
> such tests is unintuitive, because the word "unit" hints at "unit tests"
> -- and having descriptive (and not misleading) filenames is still
> important. So I hope you won't mind if *-test.c are still used where
> appropriate.

As Brendan alluded to in the talk, the popularity of KUnit for these
integration-style tests came as something of a surprise (more due to
our lack of imagination than anything else, I suspect). It's great
that it's working, though: I don't think anyone wants the world filled
with more single-use test "frameworks" than is necessary!

I guess the interesting thing to note is that we've to date not really
made a distinction between KUnit the framework and the suite of all
KUnit tests. Maybe having a separate file/module naming scheme could
be a way of making that distinction, though it'd really only appear
when loading tests as modules -- there'd be no indication in e.g.,
suite names or test results. The more obvious solution to me (at
least, based on the current proposal) would be to have "integration"
or similar be part of the suite name (and hence the filename, so
_integration_kunit.c or similar), though even I admit that that's much
uglier. Maybe the idea of having the subsystem/suite distinction be
represented in the code could pave the way to having different suites
support different suffixes like that.

Do you know of any cases where something has/would have both
unit-style tests and integration-style tests built with KUnit where
the distinction needs to be clear?

Brendan, Kees: do you have any thoughts?


> Thanks,
> -- Marco


Cheers,
-- David
Marco Elver Aug. 27, 2020, 6:28 p.m. UTC | #4
On Thu, 27 Aug 2020 at 18:17, David Gow <davidgow@google.com> wrote:
[...]
> > First of all, thanks for the talk yesterday! I only looked at this
> > because somebody pasted the LKML link. :-)
>
> No worries! Clearly this document needed linking -- even I was
> starting to suspect the reason no-one was complaining about this was
> that no-one had read it. :-)
[...]
> >
> > While I guess this ship has sailed, and *_kunit.c is the naming
> > convention now, I hope this is still just a recommendation and names of
> > the form *-test.c are not banned!
>
> The ship hasn't technically sailed until this patch is actually
> accepted. Thus far, we hadn't had any real complaints about the
> _kunit.c idea, though that may have been due to this email not
> reaching enough people. If you haven't read the discussion in
> https://lore.kernel.org/linux-kselftest/202006141005.BA19A9D3@keescook/t/#u
> it's worthwhile: the _kunit.c name is discussed, and Kees lays out
> some more detailed rationale for it as well.

Thanks, I can see the rationale. AFAIK the main concern was "it does
not distinguish it from other tests".

> > $> git grep 'KUNIT.*-test.o'
> >         drivers/base/power/Makefile:obj-$(CONFIG_PM_QOS_KUNIT_TEST) += qos-test.o
> >         drivers/base/test/Makefile:obj-$(CONFIG_KUNIT_DRIVER_PE_TEST) += property-entry-test.o
> >         fs/ext4/Makefile:obj-$(CONFIG_EXT4_KUNIT_TESTS)         += ext4-inode-test.o
> >         kernel/Makefile:obj-$(CONFIG_SYSCTL_KUNIT_TEST) += sysctl-test.o
> >         lib/Makefile:obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o
> >         lib/kunit/Makefile:obj-$(CONFIG_KUNIT_TEST) +=          kunit-test.o
> >         lib/kunit/Makefile:obj-$(CONFIG_KUNIT_TEST) +=          string-stream-test.o
> >         lib/kunit/Makefile:obj-$(CONFIG_KUNIT_EXAMPLE_TEST) +=  kunit-example-test.o
> >
> > $> git grep 'KUNIT.*_kunit.o'
> > # Returns nothing
> >
>
> This was definitely something we noted. Part of the goal of having
> _kunit.c as a filename suffix (and, perhaps more importantly, the
> _kunit module name suffix) was to have a way of both distinguishing
> KUnit tests from non-KUnit ones (of which there are quite a few
> already with -test names), and to have a way of quickly determining
> what modules contain KUnit tests. That really only works if everyone
> is using it, so the plan was to push this as much as possible. This'd
> probably include renaming most of the existing test files to match,
> which is a bit of a pain (particularly when converting non-KUnit tests
> to KUnit and similar), but is a one-time thing.

Feel free to ignore the below, but here might be one concern:

I think the problem of distinguishing KUnit tests from non-KUnit tests
is a technical problem (in fact, the Kconfig entries have all the info
we need), but a solution that sacrifices readability might cause
unnecessary friction.

The main issue I foresee is that the _kunit.c name is opaque as to
what the file does, but merely indicates one of its dependencies. Most
of us clearly know that KUnit is a test framework, but it's a level of
indirection nevertheless. (But _kunit_test.c is also bad, because it's
unnecessarily long.) For a dozen tests, that's probably still fine.
But now imagine 100s of tests, people will quickly wonder "what's this
_kunit thing?". And if KUnit tests are eventually the dominant tests,
does it still matter?

I worry that because of the difficulty of enforcing the name, choosing
something unintuitive will also achieve the opposite result:
proliferation of even more diverse names. A generic convention like
"*-test.c" will be close enough to what's intuitive for most people,
and we might actually have a chance of getting everyone to stick to
it.

The problem of identifying all KUnit tests can be solved with a script.

> > Just an idea: Maybe the names are also an opportunity to distinguish
> > real _unit_ style tests and then the rarer integration-style tests. I
> > personally prefer using the more generic *-test.c, at least for the
> > integration-style tests I've been working on (KUnit is still incredibly
> > valuable for integration-style tests, because otherwise I'd have to roll
> > my own poor-man's version of KUnit, so thank you!). Using *_kunit.c for
> > such tests is unintuitive, because the word "unit" hints at "unit tests"
> > -- and having descriptive (and not misleading) filenames is still
> > important. So I hope you won't mind if *-test.c are still used where
> > appropriate.
>
> As Brendan alluded to in the talk, the popularity of KUnit for these
> integration-style tests came as something of a surprise (more due to
> our lack of imagination than anything else, I suspect). It's great
> that it's working, though: I don't think anyone wants the world filled
> with more single-use test "frameworks" than is necessary!
>
> I guess the interesting thing to note is that we've to date not really
> made a distinction between KUnit the framework and the suite of all
> KUnit tests. Maybe having a separate file/module naming scheme could
> be a way of making that distinction, though it'd really only appear
> when loading tests as modules -- there'd be no indication in e.g.,
> suite names or test results. The more obvious solution to me (at
> least, based on the current proposal) would be to have "integration"
> or similar be part of the suite name (and hence the filename, so
> _integration_kunit.c or similar), though even I admit that that's much
> uglier.

Yeah, that's not great either.  Again, in the end it's probably
entirely up to you, but it'd be good if the filenames are descriptive
and readable (vs. a puzzle).

> Maybe the idea of having the subsystem/suite distinction be
> represented in the code could pave the way to having different suites
> support different suffixes like that.

> Do you know of any cases where something has/would have both
> unit-style tests and integration-style tests built with KUnit where
> the distinction needs to be clear?

None I know of, so probably not a big deal.

> Brendan, Kees: do you have any thoughts?
>

> Cheers,
> -- David

Thanks,
-- Marco
Brendan Higgins Aug. 27, 2020, 7:34 p.m. UTC | #5
On Thu, Aug 27, 2020 at 11:28 AM Marco Elver <elver@google.com> wrote:
>
> On Thu, 27 Aug 2020 at 18:17, David Gow <davidgow@google.com> wrote:
> [...]
> > > First of all, thanks for the talk yesterday! I only looked at this
> > > because somebody pasted the LKML link. :-)
> >
> > No worries! Clearly this document needed linking -- even I was
> > starting to suspect the reason no-one was complaining about this was
> > that no-one had read it. :-)
> [...]
> > >
> > > While I guess this ship has sailed, and *_kunit.c is the naming
> > > convention now, I hope this is still just a recommendation and names of
> > > the form *-test.c are not banned!
> >
> > The ship hasn't technically sailed until this patch is actually
> > accepted. Thus far, we hadn't had any real complaints about the
> > _kunit.c idea, though that may have been due to this email not
> > reaching enough people. If you haven't read the discussion in
> > https://lore.kernel.org/linux-kselftest/202006141005.BA19A9D3@keescook/t/#u
> > it's worthwhile: the _kunit.c name is discussed, and Kees lays out
> > some more detailed rationale for it as well.
>
> Thanks, I can see the rationale. AFAIK the main concern was "it does
> not distinguish it from other tests".

That was my understanding as well.

> > > $> git grep 'KUNIT.*-test.o'
> > >         drivers/base/power/Makefile:obj-$(CONFIG_PM_QOS_KUNIT_TEST) += qos-test.o
> > >         drivers/base/test/Makefile:obj-$(CONFIG_KUNIT_DRIVER_PE_TEST) += property-entry-test.o
> > >         fs/ext4/Makefile:obj-$(CONFIG_EXT4_KUNIT_TESTS)         += ext4-inode-test.o
> > >         kernel/Makefile:obj-$(CONFIG_SYSCTL_KUNIT_TEST) += sysctl-test.o
> > >         lib/Makefile:obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o
> > >         lib/kunit/Makefile:obj-$(CONFIG_KUNIT_TEST) +=          kunit-test.o
> > >         lib/kunit/Makefile:obj-$(CONFIG_KUNIT_TEST) +=          string-stream-test.o
> > >         lib/kunit/Makefile:obj-$(CONFIG_KUNIT_EXAMPLE_TEST) +=  kunit-example-test.o
> > >
> > > $> git grep 'KUNIT.*_kunit.o'
> > > # Returns nothing
> > >
> >
> > This was definitely something we noted. Part of the goal of having
> > _kunit.c as a filename suffix (and, perhaps more importantly, the
> > _kunit module name suffix) was to have a way of both distinguishing
> > KUnit tests from non-KUnit ones (of which there are quite a few
> > already with -test names), and to have a way of quickly determining
> > what modules contain KUnit tests. That really only works if everyone
> > is using it, so the plan was to push this as much as possible. This'd
> > probably include renaming most of the existing test files to match,
> > which is a bit of a pain (particularly when converting non-KUnit tests
> > to KUnit and similar), but is a one-time thing.
>
> Feel free to ignore the below, but here might be one concern:
>
> I think the problem of distinguishing KUnit tests from non-KUnit tests
> is a technical problem (in fact, the Kconfig entries have all the info
> we need), but a solution that sacrifices readability might cause
> unnecessary friction.
>
> The main issue I foresee is that the _kunit.c name is opaque as to
> what the file does, but merely indicates one of its dependencies. Most
> of us clearly know that KUnit is a test framework, but it's a level of
> indirection nevertheless. (But _kunit_test.c is also bad, because it's
> unnecessarily long.) For a dozen tests, that's probably still fine.
> But now imagine 100s of tests, people will quickly wonder "what's this
> _kunit thing?". And if KUnit tests are eventually the dominant tests,
> does it still matter?
>
> I worry that because of the difficulty of enforcing the name, choosing
> something unintuitive will also achieve the opposite result:
> proliferation of even more diverse names. A generic convention like
> "*-test.c" will be close enough to what's intuitive for most people,
> and we might actually have a chance of getting everyone to stick to
> it.
>
> The problem of identifying all KUnit tests can be solved with a script.

Fair point. However, converting all non-kselftests to kselftest or
KUnit will likely take time, and kselftest will likely be with us
forever. In short, other tests are likely to co-exist with KUnit for a
long time if not in perpetuity; thus, I think Kees' point stands in
this case.

> > > Just an idea: Maybe the names are also an opportunity to distinguish
> > > real _unit_ style tests and then the rarer integration-style tests. I
> > > personally prefer using the more generic *-test.c, at least for the
> > > integration-style tests I've been working on (KUnit is still incredibly
> > > valuable for integration-style tests, because otherwise I'd have to roll
> > > my own poor-man's version of KUnit, so thank you!). Using *_kunit.c for
> > > such tests is unintuitive, because the word "unit" hints at "unit tests"
> > > -- and having descriptive (and not misleading) filenames is still
> > > important. So I hope you won't mind if *-test.c are still used where
> > > appropriate.
> >
> > As Brendan alluded to in the talk, the popularity of KUnit for these
> > integration-style tests came as something of a surprise (more due to
> > our lack of imagination than anything else, I suspect). It's great
> > that it's working, though: I don't think anyone wants the world filled
> > with more single-use test "frameworks" than is necessary!
> >
> > I guess the interesting thing to note is that we've to date not really
> > made a distinction between KUnit the framework and the suite of all
> > KUnit tests. Maybe having a separate file/module naming scheme could
> > be a way of making that distinction, though it'd really only appear
> > when loading tests as modules -- there'd be no indication in e.g.,
> > suite names or test results. The more obvious solution to me (at
> > least, based on the current proposal) would be to have "integration"
> > or similar be part of the suite name (and hence the filename, so
> > _integration_kunit.c or similar), though even I admit that that's much
> > uglier.

Very good point.

> Yeah, that's not great either.  Again, in the end it's probably
> entirely up to you, but it'd be good if the filenames are descriptive
> and readable (vs. a puzzle).

Yeah, I have no good answers either.

Dumb idea: name integration tests *_kint.c. Probably worse and more
confusing than either just *_kunit.c or *_integration_{test|kunit}.c.

As misleading as it is to have the label "unit" on an integration
test, I tend to think that asking devs to label their tests properly
as either unit tests or integration tests is unrealistic.

Then again, does it really matter for anyone other than the maintainer
and devs who contribute to the test?

> > Maybe the idea of having the subsystem/suite distinction be
> > represented in the code could pave the way to having different suites
> > support different suffixes like that.

I don't think I follow.

> > Do you know of any cases where something has/would have both
> > unit-style tests and integration-style tests built with KUnit where
> > the distinction needs to be clear?
>
> None I know of, so probably not a big deal.
>
> > Brendan, Kees: do you have any thoughts?

Marco and Kees both make good points. I don't think there is a right
or wrong decision here; I think we just need to pick.

Personally, I like *-test.c, but that's probably just because that was
my original intention: I am not really sure that the costs/benefits
really make it superior to *-kunit.c.

David, it's your patch, so it's up to you; however, if you want to
pick *-test.c, and blame any consequences on me, feel free.

Cheers
Kees Cook Aug. 31, 2020, 11:47 p.m. UTC | #6
On Fri, Aug 28, 2020 at 12:17:05AM +0800, David Gow wrote:
> On Thu, Aug 27, 2020 at 9:14 PM Marco Elver <elver@google.com> wrote:
> > Just an idea: Maybe the names are also an opportunity to distinguish
> > real _unit_ style tests and then the rarer integration-style tests. I
> > personally prefer using the more generic *-test.c, at least for the
> > integration-style tests I've been working on (KUnit is still incredibly
> > valuable for integration-style tests, because otherwise I'd have to roll
> > my own poor-man's version of KUnit, so thank you!). Using *_kunit.c for
> > such tests is unintuitive, because the word "unit" hints at "unit tests"
> > -- and having descriptive (and not misleading) filenames is still
> > important. So I hope you won't mind if *-test.c are still used where
> > appropriate.

This is a good point, and I guess not one that has really been examined.
I'm not sure what to think of some of the lib/ tests. test_user_copy
seems to be a "unit" test -- it's validating the function family vs
all kinds of arguments and conditions. But test_overflow is less unit
and more integration, which includes "do all of these allocators end up
acting the same way?" etc

I'm not really sure what to make of that -- I don't really have a formal
testing background.

> As Brendan alluded to in the talk, the popularity of KUnit for these
> integration-style tests came as something of a surprise (more due to
> our lack of imagination than anything else, I suspect). It's great
> that it's working, though: I don't think anyone wants the world filled
> with more single-use test "frameworks" than is necessary!
> 
> I guess the interesting thing to note is that we've to date not really
> made a distinction between KUnit the framework and the suite of all
> KUnit tests. Maybe having a separate file/module naming scheme could
> be a way of making that distinction, though it'd really only appear
> when loading tests as modules -- there'd be no indication in e.g.,
> suite names or test results. The more obvious solution to me (at
> least, based on the current proposal) would be to have "integration"
> or similar be part of the suite name (and hence the filename, so
> _integration_kunit.c or similar), though even I admit that that's much
> uglier. Maybe the idea of having the subsystem/suite distinction be
> represented in the code could pave the way to having different suites
> support different suffixes like that.

Heh, yeah, let's not call them "_integration_kunit.c" ;) _behavior.c?
_integration.c?

> Do you know of any cases where something has/would have both
> unit-style tests and integration-style tests built with KUnit where
> the distinction needs to be clear?

This is probably the right question. :)
David Gow Sept. 1, 2020, 5:31 a.m. UTC | #7
On Tue, Sep 1, 2020 at 7:47 AM Kees Cook <keescook@chromium.org> wrote:
>
> On Fri, Aug 28, 2020 at 12:17:05AM +0800, David Gow wrote:
> > On Thu, Aug 27, 2020 at 9:14 PM Marco Elver <elver@google.com> wrote:
> > > Just an idea: Maybe the names are also an opportunity to distinguish
> > > real _unit_ style tests and then the rarer integration-style tests. I
> > > personally prefer using the more generic *-test.c, at least for the
> > > integration-style tests I've been working on (KUnit is still incredibly
> > > valuable for integration-style tests, because otherwise I'd have to roll
> > > my own poor-man's version of KUnit, so thank you!). Using *_kunit.c for
> > > such tests is unintuitive, because the word "unit" hints at "unit tests"
> > > -- and having descriptive (and not misleading) filenames is still
> > > important. So I hope you won't mind if *-test.c are still used where
> > > appropriate.
>
> This is a good point, and I guess not one that has really been examined.
> I'm not sure what to think of some of the lib/ tests. test_user_copy
> seems to be a "unit" test -- it's validating the function family vs
> all kinds of arguments and conditions. But test_overflow is less unit
> and more integration, which includes "do all of these allocators end up
> acting the same way?" etc
>
> I'm not really sure what to make of that -- I don't really have a formal
> testing background.
>

I'm not sure we need a super-precise definition here (maybe just
because I don't have one), and really just need to work out what
distinctions are actually useful. For example, I'm not sure there's
any real advantage to treating test_user_copy and test_overflow
differently. The KCSAN tests which spawn lots of threads and are both
slower and less deterministic seem more obviously different, though.

I guess there are two audiences to cater for:
1. Test authors, who may wish to have both unit-style and
integration-style tests, and want to distinguish them. They probably
have the best idea of where the line should be drawn for their
subsystems, and may have some existing style/nomenclature.
2. People running "all tests", who want to broadly understand how the
whole suite of tests will behave (e.g., how long they'll take to run,
are they possibly nondeterministic, are there weird hardware/software
dependencies). This is where some more standardisation probably makes
sense.

I'm not 100% the file/module name is the best place to make these
distinctions (given that it's the Kconfig entries that are at least
our current way of finding and running tests). An off-the-wall idea
would be to have a flags field in the test suite structure to note
things like "large/long-running test" or "nondeterministic", and have
either a KUnit option to bypass them, note them in the output, or even
something terrifying like parsing it out of a compiled module.

> > As Brendan alluded to in the talk, the popularity of KUnit for these
> > integration-style tests came as something of a surprise (more due to
> > our lack of imagination than anything else, I suspect). It's great
> > that it's working, though: I don't think anyone wants the world filled
> > with more single-use test "frameworks" than is necessary!
> >
> > I guess the interesting thing to note is that we've to date not really
> > made a distinction between KUnit the framework and the suite of all
> > KUnit tests. Maybe having a separate file/module naming scheme could
> > be a way of making that distinction, though it'd really only appear
> > when loading tests as modules -- there'd be no indication in e.g.,
> > suite names or test results. The more obvious solution to me (at
> > least, based on the current proposal) would be to have "integration"
> > or similar be part of the suite name (and hence the filename, so
> > _integration_kunit.c or similar), though even I admit that that's much
> > uglier. Maybe the idea of having the subsystem/suite distinction be
> > represented in the code could pave the way to having different suites
> > support different suffixes like that.
>
> Heh, yeah, let's not call them "_integration_kunit.c" ;) _behavior.c?
> _integration.c?
>

I think we'd really like something that says more strongly that this
is a test (which is I suspect one of the reasons why _kunit.c has its
detractors: it doesn't have the word "test" in it). The other thing to
consider is that if there are multiple tests for the same thing (e.g.,
a unit test suite and an integration test suite), they'd still need
separate, non-conflicting suite names if we wanted them to be able to
be present in the same kernel.

Maybe the right thing to do is to say that, for now, the _kunit.c
naming guideline only applies to "unit-style" tests.

> > Do you know of any cases where something has/would have both
> > unit-style tests and integration-style tests built with KUnit where
> > the distinction needs to be clear?
>
> This is probably the right question. :)
>
I had a quick look, and we don't appear to have anything quite like
this yet, at least with KUnit.


So, putting together the various bits of feedback, how about something
like this:
Test filenames/modules should end in _kunit.c, unless they are either
a) not unit-style tests -- i.e, test something other than correctness
(e.g., performance), are non-deterministic, take a long time to run (>
~1--2 seconds), or are testing across multiple subsystems -- OR
b) are ports of existing tests, which may keep their existing filename
(at least for now), so as not to break existing workflows.

This is a bit weaker than the existing guidelines, and will probably
need tightening up once we have a better idea of what non-unit tests
should be and/or the existing, inconsistently named tests are
sufficiently outnumbered by the _kunit ones that people are used to it
and the perceived ugliness fades away. What (if any) tooling we need
around enumerating tests may end up influencing/being influenced by
this a bit, too.

Thoughts?
-- David
Marco Elver Sept. 1, 2020, 12:23 p.m. UTC | #8
On Tue, 1 Sep 2020 at 07:31, David Gow <davidgow@google.com> wrote:
> On Tue, Sep 1, 2020 at 7:47 AM Kees Cook <keescook@chromium.org> wrote:
> > On Fri, Aug 28, 2020 at 12:17:05AM +0800, David Gow wrote:
> > > On Thu, Aug 27, 2020 at 9:14 PM Marco Elver <elver@google.com> wrote:
[...]
>
> I guess there are two audiences to cater for:
> 1. Test authors, who may wish to have both unit-style and
> integration-style tests, and want to distinguish them. They probably
> have the best idea of where the line should be drawn for their
> subsystems, and may have some existing style/nomenclature.
> 2. People running "all tests", who want to broadly understand how the
> whole suite of tests will behave (e.g., how long they'll take to run,
> are they possibly nondeterministic, are there weird hardware/software
> dependencies). This is where some more standardisation probably makes
> sense.
>
> I'm not 100% the file/module name is the best place to make these
> distinctions (given that it's the Kconfig entries that are at least
> our current way of finding and running tests).

I agree -- as you note, it's very hard to make this distinction. Since
we're still discussing the best convention to use, one point I want to
make is that encoding a dependency ("kunit") or type of test (unit,
integration, etc.) in the name hurts scalability of our workflows.
Because as soon as the dependency changes, or the type, any
rename/move is very destructive to our workflow, because it
immediately causes conflict with any in-flight patches. Whereas
encoding this either in a comment, or via Kconfig would be less
destructive.

> An off-the-wall idea
> would be to have a flags field in the test suite structure to note
> things like "large/long-running test" or "nondeterministic", and have
> either a KUnit option to bypass them, note them in the output, or even
> something terrifying like parsing it out of a compiled module.

As a side-node, in the other very large codebase I have worked on, we
have such markers ("size = ..."):
https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes-tests
However, there is also incentive to get this distinction right,
because the test will be killed by the CI system if it exceeds the
specified size (ran too long, OOM). Not sure we have this incentive
yet.

[...]
> > > I guess the interesting thing to note is that we've to date not really
> > > made a distinction between KUnit the framework and the suite of all
> > > KUnit tests. Maybe having a separate file/module naming scheme could
> > > be a way of making that distinction, though it'd really only appear
> > > when loading tests as modules -- there'd be no indication in e.g.,
> > > suite names or test results. The more obvious solution to me (at
> > > least, based on the current proposal) would be to have "integration"
> > > or similar be part of the suite name (and hence the filename, so
> > > _integration_kunit.c or similar), though even I admit that that's much
> > > uglier. Maybe the idea of having the subsystem/suite distinction be
> > > represented in the code could pave the way to having different suites
> > > support different suffixes like that.
> >
> > Heh, yeah, let's not call them "_integration_kunit.c" ;) _behavior.c?
> > _integration.c?

If possible, I'd still prefer generic filenames, because it's easy to
get wrong as we noted. Changes will cause conflicts.

> I think we'd really like something that says more strongly that this
> is a test (which is I suspect one of the reasons why _kunit.c has its
> detractors: it doesn't have the word "test" in it).

^ Agreed.

> The other thing to
> consider is that if there are multiple tests for the same thing (e.g.,
> a unit test suite and an integration test suite), they'd still need
> separate, non-conflicting suite names if we wanted them to be able to
> be present in the same kernel.
>
> Maybe the right thing to do is to say that, for now, the _kunit.c
> naming guideline only applies to "unit-style" tests.
[...]
>
> So, putting together the various bits of feedback, how about something
> like this:
> Test filenames/modules should end in _kunit.c, unless they are either
> a) not unit-style tests -- i.e, test something other than correctness
> (e.g., performance), are non-deterministic, take a long time to run (>
> ~1--2 seconds), or are testing across multiple subsystems -- OR
> b) are ports of existing tests, which may keep their existing filename
> (at least for now), so as not to break existing workflows.
>
> This is a bit weaker than the existing guidelines, and will probably
> need tightening up once we have a better idea of what non-unit tests
> should be and/or the existing, inconsistently named tests are
> sufficiently outnumbered by the _kunit ones that people are used to it
> and the perceived ugliness fades away. What (if any) tooling we need
> around enumerating tests may end up influencing/being influenced by
> this a bit, too.
>
> Thoughts?

That could work, but it all still feels a little unsatisfying. Here's
what I think the requirements for all this are:

1. Clear, intuitive, descriptive filenames ("[...] something that says
more strongly that this is a test [...]").

2. Avoid renames if any of the following changes: test framework, test
type or scope. I worry the most about this point, because it affects
our workflows. We need to avoid unnecessary patch conflicts, keep
cherry-picks simple, etc.

3. Strive for consistently named tests, regardless of type (because
it's hard to get right).

4. Want to distinguish KUnit tests from non-KUnit tests. (Also
consider that tooling can assist with this.)

These are the 2 options under closer consideration:

A. Original choice of "*-test.c": Satisfies 1,2,3. It seems to fail 4,
per Kees's original concern.

B. "*_kunit.c": Satisfies 4, maybe 3.
  - Fails 1, because !strstr("_kunit.c", "test") and the resulting
indirection. It hints at "unit test", but this may be a problem for
(2).
  - Fails 2, because if the test for some reason decides to stop using
KUnit (or a unit test morphs into an integration test), the file needs
to be renamed.

And based on all this, why not:

C. "*-ktest.c" (or "*_ktest.c"):
  - Satisfies 1, because it's descriptive and clearly says it's a
test; the 'k' can suggest it's an "[in-]kernel test" vs. some other
hybrid test that requires a userspace component.
  - Satisfies 2, because neither test framework or test type need to
be encoded in the filename.
  - Satisfies 3, because every test (that wants to use KUnit) can just
use this without thinking too much about it.
  - Satisfies 4, because "git grep -- '[-_]ktest\.[co]'" returns nothing.

Thanks,
-- Marco
David Gow Sept. 4, 2020, 4:22 a.m. UTC | #9
On Tue, Sep 1, 2020 at 8:23 PM Marco Elver <elver@google.com> wrote:
>
> On Tue, 1 Sep 2020 at 07:31, David Gow <davidgow@google.com> wrote:
> > On Tue, Sep 1, 2020 at 7:47 AM Kees Cook <keescook@chromium.org> wrote:
> > > On Fri, Aug 28, 2020 at 12:17:05AM +0800, David Gow wrote:
> > > > On Thu, Aug 27, 2020 at 9:14 PM Marco Elver <elver@google.com> wrote:
> [...]
> >
> > I guess there are two audiences to cater for:
> > 1. Test authors, who may wish to have both unit-style and
> > integration-style tests, and want to distinguish them. They probably
> > have the best idea of where the line should be drawn for their
> > subsystems, and may have some existing style/nomenclature.
> > 2. People running "all tests", who want to broadly understand how the
> > whole suite of tests will behave (e.g., how long they'll take to run,
> > are they possibly nondeterministic, are there weird hardware/software
> > dependencies). This is where some more standardisation probably makes
> > sense.
> >
> > I'm not 100% the file/module name is the best place to make these
> > distinctions (given that it's the Kconfig entries that are at least
> > our current way of finding and running tests).
>
> I agree -- as you note, it's very hard to make this distinction. Since
> we're still discussing the best convention to use, one point I want to
> make is that encoding a dependency ("kunit") or type of test (unit,
> integration, etc.) in the name hurts scalability of our workflows.
> Because as soon as the dependency changes, or the type, any
> rename/move is very destructive to our workflow, because it
> immediately causes conflict with any in-flight patches. Whereas
> encoding this either in a comment, or via Kconfig would be less
> destructive.
>

This is a good point -- renaming files is definitely a pain. It's
obviously my hope that KUnit sticks around long enough that it's not
being added/removed as a dependency too often, particularly for the
unit tests, so "_kunit" as a name doesn't worry me that much
otherwise.

> > An off-the-wall idea
> > would be to have a flags field in the test suite structure to note
> > things like "large/long-running test" or "nondeterministic", and have
> > either a KUnit option to bypass them, note them in the output, or even
> > something terrifying like parsing it out of a compiled module.
>
> As a side-node, in the other very large codebase I have worked on, we
> have such markers ("size = ..."):
> https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes-tests
> However, there is also incentive to get this distinction right,
> because the test will be killed by the CI system if it exceeds the
> specified size (ran too long, OOM). Not sure we have this incentive
> yet.
>

KUnit does have test timeouts, but they're generous (30 seconds), and
not configurable per-test or per-suite. Fixing that's probably a
separate feature request which, as you point out, probably isn't worth
doing until we're actually seeing a problem. Maybe it's something
that'll become more apparent as KUnit is integrated into KernelCI and
the like, so we see more (and more varied) test runs/configs.

> [...]
> > > > I guess the interesting thing to note is that we've to date not really
> > > > made a distinction between KUnit the framework and the suite of all
> > > > KUnit tests. Maybe having a separate file/module naming scheme could
> > > > be a way of making that distinction, though it'd really only appear
> > > > when loading tests as modules -- there'd be no indication in e.g.,
> > > > suite names or test results. The more obvious solution to me (at
> > > > least, based on the current proposal) would be to have "integration"
> > > > or similar be part of the suite name (and hence the filename, so
> > > > _integration_kunit.c or similar), though even I admit that that's much
> > > > uglier. Maybe the idea of having the subsystem/suite distinction be
> > > > represented in the code could pave the way to having different suites
> > > > support different suffixes like that.
> > >
> > > Heh, yeah, let's not call them "_integration_kunit.c" ;) _behavior.c?
> > > _integration.c?
>
> If possible, I'd still prefer generic filenames, because it's easy to
> get wrong as we noted. Changes will cause conflicts.
>
> > I think we'd really like something that says more strongly that this
> > is a test (which is I suspect one of the reasons why _kunit.c has its
> > detractors: it doesn't have the word "test" in it).
>
> ^ Agreed.
>

I'm not personally convinced that "kunit" isn't something people could
associate with tests, particularly as it becomes more popular, but if
people really dislike it, we could have"_unittest.c" or similar.
There's a balancing act between being generic (and not distinguishing
between unit/integration/etc tests) and being consistent or avoiding
renames. Take the case where there's a set of unit tests in a
"-test.c" file, and an integration test is written as well: it
probably should go in a speparate file, so now you'd either have a
"-test.c" and a separate "-integration-test.c" (or the other way
around if the integration test was written first), or the "-test.c"
file would be renamed.

> > The other thing to
> > consider is that if there are multiple tests for the same thing (e.g.,
> > a unit test suite and an integration test suite), they'd still need
> > separate, non-conflicting suite names if we wanted them to be able to
> > be present in the same kernel.
> >
> > Maybe the right thing to do is to say that, for now, the _kunit.c
> > naming guideline only applies to "unit-style" tests.
> [...]
> >
> > So, putting together the various bits of feedback, how about something
> > like this:
> > Test filenames/modules should end in _kunit.c, unless they are either
> > a) not unit-style tests -- i.e, test something other than correctness
> > (e.g., performance), are non-deterministic, take a long time to run (>
> > ~1--2 seconds), or are testing across multiple subsystems -- OR
> > b) are ports of existing tests, which may keep their existing filename
> > (at least for now), so as not to break existing workflows.
> >
> > This is a bit weaker than the existing guidelines, and will probably
> > need tightening up once we have a better idea of what non-unit tests
> > should be and/or the existing, inconsistently named tests are
> > sufficiently outnumbered by the _kunit ones that people are used to it
> > and the perceived ugliness fades away. What (if any) tooling we need
> > around enumerating tests may end up influencing/being influenced by
> > this a bit, too.
> >
> > Thoughts?
>
> That could work, but it all still feels a little unsatisfying. Here's
> what I think the requirements for all this are:
>
> 1. Clear, intuitive, descriptive filenames ("[...] something that says
> more strongly that this is a test [...]").
>
> 2. Avoid renames if any of the following changes: test framework, test
> type or scope. I worry the most about this point, because it affects
> our workflows. We need to avoid unnecessary patch conflicts, keep
> cherry-picks simple, etc.
>
> 3. Strive for consistently named tests, regardless of type (because
> it's hard to get right).
>
> 4. Want to distinguish KUnit tests from non-KUnit tests. (Also
> consider that tooling can assist with this.)
>

I think that these are somewhat in conflict with each other, which is
what makes this complicated. Particularly, it's going to be difficult
to both avoid renames if the test framework changes and to distinguish
between KUnit and non-KUnit tests by filename.

I personally think that of these requirements, 2 is probably the one
that would cause people the most real-world pain. I'm not sure how
often test type or scope changes enough to be worth the rename, and I
hope KUnit survives long enough and is useful enough that test
framework changes are kept to a minimum, but this has already
irritated enough people porting tests to KUnit to be a noticeable
issue. One possibility is to focus on module names, which are probably
more important and can be renamed without changing the filename,
though that's pretty ugly.

I actually think "_kunit.c" probably is descriptive/intuitive enough
to meet (1) -- or at least will be once KUnit is more widely used --
but it does conflict a bit with 2.

It'd be nice to have consistently named tests, but we're not there at
the moment, so fixing it will require a lot of renaming things. It's
looking increasingly unlikely that we'll be able to do that for
everything, so making this a recommendation for new test suites is
probably the best we're likely to get.

> These are the 2 options under closer consideration:
>
> A. Original choice of "*-test.c": Satisfies 1,2,3. It seems to fail 4,
> per Kees's original concern.
>

Kees also brings up that using hyphens instead of underscores causes
some inconsistency with module names, which is a bit of a pain.

> B. "*_kunit.c": Satisfies 4, maybe 3.
>   - Fails 1, because !strstr("_kunit.c", "test") and the resulting
> indirection. It hints at "unit test", but this may be a problem for
> (2).
>   - Fails 2, because if the test for some reason decides to stop using
> KUnit (or a unit test morphs into an integration test), the file needs
> to be renamed.
>
> And based on all this, why not:
>
> C. "*-ktest.c" (or "*_ktest.c"):
>   - Satisfies 1, because it's descriptive and clearly says it's a
> test; the 'k' can suggest it's an "[in-]kernel test" vs. some other
> hybrid test that requires a userspace component.
>   - Satisfies 2, because neither test framework or test type need to
> be encoded in the filename.
>   - Satisfies 3, because every test (that wants to use KUnit) can just
> use this without thinking too much about it.
>   - Satisfies 4, because "git grep -- '[-_]ktest\.[co]'" returns nothing.
>

My concern with this is that we're introducing new jargon either way:
does having "test" in the name outweigh the potential confusion from
having "ktest" be in the filename only for "KUnit tests". So my
feeling is that this would've been really useful if we'd named KUnit
KTest (which, ironically, I think Brendan had considered) instead, but
as-is is probably more confusing.

> Thanks,
> -- Marco

At the risk of just chickening out at calling this "too hard", I'm
leaning towards a variant of (A) here, and going for _test, but making
it a weaker recommendation:
- Specifying that the module name should end in _test, rather than the
source filename. Module names are easier to change without causing
merge conflicts (though they're a pain to change for the user).
- Only applies to new test suites, and another suffix may be used if
it conflicts with an existing non-kunit test (if it conflicts with a
kunit test, they should be disambiguated in the suite name).
- Test types (unit, integration, some subsystem-specific thing, etc)
may be disambiguated in the suite name, at the discretion of the test
author. (e.g., "driver_integration" as a suite name, with
"driver_integration_test" as the module name, and either
"driver_integration_test.c" or "integration_test.c" as recommended
test filenames, depending on if "driver" is in its own directory.)

This should satisfy 1 & 2, and go some way towards satisfying 3. We
can try to come up with some other technical solution to 4 if we need
to.

Unless the objections are particularly earth-shattering, I'll do a new
version of the patch that matches this next week. The other option is
to drop the filename stuff from the document altogether, and sort it
out in another patch, so we at least get some of the consistency in
suite and Kconfig names.

Cheers,
-- David
Marco Elver Sept. 7, 2020, 8:57 a.m. UTC | #10
On Fri, Sep 04, 2020 at 12:22PM +0800, David Gow wrote:
[...]
> 
> This is a good point -- renaming files is definitely a pain. It's
> obviously my hope that KUnit sticks around long enough that it's not
> being added/removed as a dependency too often, particularly for the
> unit tests, so "_kunit" as a name doesn't worry me that much
> otherwise.

Make sense. And I do also hope that once a test is a KUnit test, there
is no need to change it. :-)

[...]
> I'm not personally convinced that "kunit" isn't something people could
> associate with tests, particularly as it becomes more popular, but if
> people really dislike it, we could have"_unittest.c" or similar.
> There's a balancing act between being generic (and not distinguishing
> between unit/integration/etc tests) and being consistent or avoiding
> renames. Take the case where there's a set of unit tests in a
> "-test.c" file, and an integration test is written as well: it
> probably should go in a speparate file, so now you'd either have a
> "-test.c" and a separate "-integration-test.c" (or the other way
> around if the integration test was written first), or the "-test.c"
> file would be renamed.

Makes sense, too. Yeah, if we have both we'd need to distinguish one way
or another. What might be particularly annoying is the case if an
integration test exists first, and it had been named "_kunit.c",
followed by addition of a unit test. I think the only sane thing at that
point would be to do a rename of the integration test; whereas if it had
been named "_test.c", I could live with there simply being a
"_unit_test.c" (or similar) file for the new unit test.

[...]
> > 1. Clear, intuitive, descriptive filenames ("[...] something that says
> > more strongly that this is a test [...]").
> >
> > 2. Avoid renames if any of the following changes: test framework, test
> > type or scope. I worry the most about this point, because it affects
> > our workflows. We need to avoid unnecessary patch conflicts, keep
> > cherry-picks simple, etc.
> >
> > 3. Strive for consistently named tests, regardless of type (because
> > it's hard to get right).
> >
> > 4. Want to distinguish KUnit tests from non-KUnit tests. (Also
> > consider that tooling can assist with this.)
> >
> 
> I think that these are somewhat in conflict with each other, which is
> what makes this complicated. Particularly, it's going to be difficult
> to both avoid renames if the test framework changes and to distinguish
> between KUnit and non-KUnit tests by filename.
> 
> I personally think that of these requirements, 2 is probably the one
> that would cause people the most real-world pain. I'm not sure how
> often test type or scope changes enough to be worth the rename, and I
> hope KUnit survives long enough and is useful enough that test
> framework changes are kept to a minimum, but this has already
> irritated enough people porting tests to KUnit to be a noticeable
> issue. One possibility is to focus on module names, which are probably
> more important and can be renamed without changing the filename,
> though that's pretty ugly.
> 
> I actually think "_kunit.c" probably is descriptive/intuitive enough
> to meet (1) -- or at least will be once KUnit is more widely used --
> but it does conflict a bit with 2.
> 
> It'd be nice to have consistently named tests, but we're not there at
> the moment, so fixing it will require a lot of renaming things. It's
> looking increasingly unlikely that we'll be able to do that for
> everything, so making this a recommendation for new test suites is
> probably the best we're likely to get.
> 
> > These are the 2 options under closer consideration:
> >
> > A. Original choice of "*-test.c": Satisfies 1,2,3. It seems to fail 4,
> > per Kees's original concern.
> >
> 
> Kees also brings up that using hyphens instead of underscores causes
> some inconsistency with module names, which is a bit of a pain.
> 
> > B. "*_kunit.c": Satisfies 4, maybe 3.
> >   - Fails 1, because !strstr("_kunit.c", "test") and the resulting
> > indirection. It hints at "unit test", but this may be a problem for
> > (2).
> >   - Fails 2, because if the test for some reason decides to stop using
> > KUnit (or a unit test morphs into an integration test), the file needs
> > to be renamed.
> >
> > And based on all this, why not:
> >
> > C. "*-ktest.c" (or "*_ktest.c"):
> >   - Satisfies 1, because it's descriptive and clearly says it's a
> > test; the 'k' can suggest it's an "[in-]kernel test" vs. some other
> > hybrid test that requires a userspace component.
> >   - Satisfies 2, because neither test framework or test type need to
> > be encoded in the filename.
> >   - Satisfies 3, because every test (that wants to use KUnit) can just
> > use this without thinking too much about it.
> >   - Satisfies 4, because "git grep -- '[-_]ktest\.[co]'" returns nothing.
> >
> 
> My concern with this is that we're introducing new jargon either way:
> does having "test" in the name outweigh the potential confusion from
> having "ktest" be in the filename only for "KUnit tests". So my
> feeling is that this would've been really useful if we'd named KUnit
> KTest (which, ironically, I think Brendan had considered) instead, but
> as-is is probably more confusing.

Make sense, too.

> At the risk of just chickening out at calling this "too hard", I'm
> leaning towards a variant of (A) here, and going for _test, but making
> it a weaker recommendation:
> - Specifying that the module name should end in _test, rather than the
> source filename. Module names are easier to change without causing
> merge conflicts (though they're a pain to change for the user).
> - Only applies to new test suites, and another suffix may be used if
> it conflicts with an existing non-kunit test (if it conflicts with a
> kunit test, they should be disambiguated in the suite name).
> - Test types (unit, integration, some subsystem-specific thing, etc)
> may be disambiguated in the suite name, at the discretion of the test
> author. (e.g., "driver_integration" as a suite name, with
> "driver_integration_test" as the module name, and either
> "driver_integration_test.c" or "integration_test.c" as recommended
> test filenames, depending on if "driver" is in its own directory.)
> 
> This should satisfy 1 & 2, and go some way towards satisfying 3. We
> can try to come up with some other technical solution to 4 if we need
> to.
> 
> Unless the objections are particularly earth-shattering, I'll do a new
> version of the patch that matches this next week. The other option is
> to drop the filename stuff from the document altogether, and sort it
> out in another patch, so we at least get some of the consistency in
> suite and Kconfig names.

Thanks for the detailed answer. Your plan sounds good to me. I'm fine
either way, as long as requirement (2) is somehow addressed, and we do
not end up with unnecessary renames.

Thanks,
-- Marco

Patch
diff mbox series

diff --git a/Documentation/dev-tools/kunit/index.rst b/Documentation/dev-tools/kunit/index.rst
index e93606ecfb01..c234a3ab3c34 100644
--- a/Documentation/dev-tools/kunit/index.rst
+++ b/Documentation/dev-tools/kunit/index.rst
@@ -11,6 +11,7 @@  KUnit - Unit Testing for the Linux Kernel
 	usage
 	kunit-tool
 	api/index
+	style
 	faq
 
 What is KUnit?
diff --git a/Documentation/dev-tools/kunit/style.rst b/Documentation/dev-tools/kunit/style.rst
new file mode 100644
index 000000000000..8cad2627924c
--- /dev/null
+++ b/Documentation/dev-tools/kunit/style.rst
@@ -0,0 +1,181 @@ 
+.. SPDX-License-Identifier: GPL-2.0
+
+===========================
+Test Style and Nomenclature
+===========================
+
+Subsystems, Suites, and Tests
+=============================
+
+In order to make tests as easy to find as possible, they're grouped into suites
+and subsystems. A test suite is a group of tests which test a related area of
+the kernel, and a subsystem is a set of test suites which test different parts
+of the same kernel subsystem or driver.
+
+Subsystems
+----------
+
+Every test suite must belong to a subsystem. A subsystem is a collection of one
+or more KUnit test suites which test the same driver or part of the kernel. A
+rule of thumb is that a test subsystem should match a single kernel module. If
+the code being tested can't be compiled as a module, in many cases the subsystem
+should correspond to a directory in the source tree or an entry in the
+MAINTAINERS file. If unsure, follow the conventions set by tests in similar
+areas.
+
+Test subsystems should be named after the code being tested, either after the
+module (wherever possible), or after the directory or files being tested. Test
+subsystems should be named to avoid ambiguity where necessary.
+
+If a test subsystem name has multiple components, they should be separated by
+underscores. *Do not* include "test" or "kunit" directly in the subsystem name
+unless you are actually testing other tests or the kunit framework itself.
+
+Example subsystems could be:
+
+``ext4``
+  Matches the module and filesystem name.
+``apparmor``
+  Matches the module name and LSM name.
+``kasan``
+  Common name for the tool, prominent part of the path ``mm/kasan``
+``snd_hda_codec_hdmi``
+  Has several components (``snd``, ``hda``, ``codec``, ``hdmi``) separated by
+  underscores. Matches the module name.
+
+Avoid names like these:
+
+``linear-ranges``
+  Names should use underscores, not dashes, to separate words. Prefer
+  ``linear_ranges``.
+``qos-kunit-test``
+  As well as using underscores, this name should not have "kunit-test" as a
+  suffix, and ``qos`` is ambiguous as a subsystem name. ``power_qos`` would be a
+  better name.
+``pc_parallel_port``
+  The corresponding module name is ``parport_pc``, so this subsystem should also
+  be named ``parport_pc``.
+
+.. note::
+        The KUnit API and tools do not explicitly know about subsystems. They're
+        simply a way of categorising test suites and naming modules which
+        provides a simple, consistent way for humans to find and run tests. This
+        may change in the future, though.
+
+Suites
+------
+
+KUnit tests are grouped into test suites, which cover a specific area of
+functionality being tested. Test suites can have shared initialisation and
+shutdown code which is run for all tests in the suite.
+Not all subsystems will need to be split into multiple test suites (e.g. simple drivers).
+
+Test suites are named after the subsystem they are part of. If a subsystem
+contains several suites, the specific area under test should be appended to the
+subsystem name, separated by an underscore.
+
+The full test suite name (including the subsystem name) should be specified as
+the ``.name`` member of the ``kunit_suite`` struct, and forms the base for the
+module name (see below).
+
+Example test suites could include:
+
+``ext4_inode``
+  Part of the ``ext4`` subsystem, testing the ``inode`` area.
+``kunit_try_catch``
+  Part of the ``kunit`` implementation itself, testing the ``try_catch`` area.
+``apparmor_property_entry``
+  Part of the ``apparmor`` subsystem, testing the ``property_entry`` area.
+``kasan``
+  The ``kasan`` subsystem has only one suite, so the suite name is the same as
+  the subsystem name.
+
+Avoid names like:
+
+``ext4_ext4_inode``
+  There's no reason to state the subsystem twice.
+``property_entry``
+  The suite name is ambiguous without the subsystem name.
+``kasan_unit_test``
+  Because there is only one suite in the ``kasan`` subsystem, the suite should
+  just be called ``kasan``. There's no need to redundantly add ``unit_test``.
+
+Test Cases
+----------
+
+Individual tests consist of a single function which tests a constrained
+codepath, property, or function. In the test output, individual tests' results
+will show up as subtests of the suite's results.
+
+Tests should be named after what they're testing. This is often the name of the
+function being tested, with a description of the input or codepath being tested.
+As tests are C functions, they should be named and written in accordance with
+the kernel coding style.
+
+.. note::
+        As tests are themselves functions, their names cannot conflict with
+        other C identifiers in the kernel. This may require some creative
+        naming. It's a good idea to make your test functions `static` to avoid
+        polluting the global namespace.
+
+Example test names include:
+
+``unpack_u32_with_null_name``
+  Tests the ``unpack_u32`` function when a NULL name is passed in.
+``test_list_splice``
+  Tests the ``list_splice`` macro. It has the prefix ``test_`` to avoid a
+  name conflict with the macro itself.
+
+
+Should it be necessary to refer to a test outside the context of its test suite,
+the *fully-qualified* name of a test should be the suite name followed by the
+test name, separated by a colon (i.e. ``suite:test``).
+
+Test Kconfig Entries
+====================
+
+Every test suite should be tied to a Kconfig entry.
+
+This Kconfig entry must:
+
+* be named ``CONFIG_<name>_KUNIT_TEST``: where <name> is the name of the test
+  suite.
+* be listed either alongside the config entries for the driver/subsystem being
+  tested, or be under [Kernel Hacking]→[Kernel Testing and Coverage]
+* depend on ``CONFIG_KUNIT``
+* be visible only if ``CONFIG_KUNIT_ALL_TESTS`` is not enabled.
+* have a default value of ``CONFIG_KUNIT_ALL_TESTS``.
+* have a brief description of KUnit in the help text
+
+Unless there's a specific reason not to (e.g. the test is unable to be built as
+a module), Kconfig entries for tests should be tristate.
+
+An example Kconfig entry:
+
+.. code-block:: none
+
+        config FOO_KUNIT_TEST
+                tristate "KUnit test for foo" if !KUNIT_ALL_TESTS
+                depends on KUNIT
+                default KUNIT_ALL_TESTS
+                help
+                    This builds unit tests for foo.
+
+                    For more information on KUnit and unit tests in general, please refer
+                    to the KUnit documentation in Documentation/dev-tools/kunit
+
+                    If unsure, say N
+
+
+Test Filenames
+==============
+
+Where possible, test suites should be placed in a separate source file in the
+same directory as the code being tested.
+
+This file should be named ``<suite>_kunit.c``. It may make sense to strip
+excessive namespacing from the source filename (e.g., ``firmware_kunit.c`` instead of
+``<drivername>_firmware.c``), but please ensure the module name does contain the
+full suite name.
+
+